<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Didicodes</title>
    <description>The latest articles on Forem by Didicodes (@didicodes).</description>
    <link>https://forem.com/didicodes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F194278%2F00703c48-2184-47e0-8fd6-1881a52e0761.jpeg</url>
      <title>Forem: Didicodes</title>
      <link>https://forem.com/didicodes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/didicodes"/>
    <language>en</language>
    <item>
      <title>How to Build a Full-Stack App With TanStack Start and MongoDB</title>
      <dc:creator>Didicodes</dc:creator>
      <pubDate>Wed, 17 Dec 2025 22:25:52 +0000</pubDate>
      <link>https://forem.com/mongodb/how-to-build-a-full-stack-app-with-tanstack-start-and-mongodb-21do</link>
      <guid>https://forem.com/mongodb/how-to-build-a-full-stack-app-with-tanstack-start-and-mongodb-21do</guid>
      <description>&lt;p&gt;&lt;strong&gt;What you'll learn&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  How TanStack Start unifies routing, data loading, server functions, and SSR in a single full-stack workflow&lt;/li&gt;
&lt;li&gt;  How to integrate MongoDB with TanStack Start using a reusable, serverless-friendly connection&lt;/li&gt;
&lt;li&gt;  How to build a CRUD Notes app with real-time UI updates using server functions instead of API routes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Building full-stack JavaScript applications often means choosing between two extremes: heavyweight frameworks that make too many decisions for you, or bare-bones setups that leave you wiring everything together manually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tanstack.com/start/latest" rel="noopener noreferrer"&gt;TanStack Start&lt;/a&gt; offers a different approach. It's a full-stack React framework designed to make building web applications simple, fast, and flexible. Built on top of &lt;a href="https://tanstack.com/router/latest" rel="noopener noreferrer"&gt;TanStack Router&lt;/a&gt;, Vite, and TypeScript, it brings together type-safe routing, client-side interactivity, server functions, SSR, and universal deployment in a clean, composable setup that's easy to work with.&lt;/p&gt;

&lt;p&gt;Although TanStack Start is still in early release, it has quickly gained attention for its lightweight, explicit design. Rather than acting like a monolithic "batteries-included" framework, it gives you full control. You choose your backend, database, and architecture while still benefiting from solid conventions and powerful tools.&lt;/p&gt;

&lt;p&gt;In this tutorial, you'll learn how TanStack Start works with MongoDB by building a simple full-stack Notes application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;This tutorial assumes that you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Node.js 18+ installed (npm is included by default)&lt;/li&gt;
&lt;li&gt;  MongoDB Atlas account or MongoDB Community Server/Edition&lt;/li&gt;
&lt;li&gt;  Basic knowledge of React and TypeScript&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using TanStack Start and MongoDB
&lt;/h2&gt;

&lt;p&gt;To build our Notes app (&lt;a href="https://github.com/mongodb-developer/tanstack-start-mongodb-notesapp" rel="noopener noreferrer"&gt;see the code repository&lt;/a&gt;), we'll use TanStack Start alongside MongoDB. TanStack Start takes care of things like routing, server logic, and data fetching in a way that feels clean and predictable, and MongoDB gives us flexible, document-based storage that fits nicely into server functions. Put together, they give us a simple full-stack workflow without the overhead of a heavier framework. Let's start building. 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a new TanStack Start project 
&lt;/h2&gt;

&lt;p&gt;There are many ways to get a TanStack Start project up and running, but for this tutorial, we will use their &lt;a href="https://github.com/TanStack/router/tree/main/examples/react/start-basic" rel="noopener noreferrer"&gt;Start-Basic&lt;/a&gt; starter template. To use it, we'll use gitpick (a tool for cloning specific folders from a Git repository) to clone just the starter template into a folder called tanstack-start-mongodb-notesapp:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx gitpick TanStack/router/tree/main/examples/react/start-basic tanstack-start-mongodb-notesapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, run the commands below to switch to the &lt;code&gt;tanstack-start-mongodb-notesapp&lt;/code&gt; directory, install the required dependencies, and start the development server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;tanstack-start-mongodb-notesapp
npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After doing this, the starter template application will run in your browser at &lt;code&gt;http://localhost:3000&lt;/code&gt;. It should look similar to the one in the image below. Feel free to play around with it to get a sense of how TanStack Start works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3gb7zgirkzii2tdt0zz6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3gb7zgirkzii2tdt0zz6.png" alt="TanStack Start's starter template application" width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, head back to your terminal and install the additional dependencies listed below, as we will need them to build our Notes application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Installs the official MongoDB Node.js driver&lt;/span&gt;
&lt;span class="c"&gt;# 2. Installs a TypeScript-first schema validation&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;mongodb zod

&lt;span class="c"&gt;# Installs dev dependencies for environment variables and running TypeScript files&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; dotenv tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Understanding the project structure for the app
&lt;/h2&gt;

&lt;p&gt;With our TanStack Start project now up and running, the next step is to remove the boilerplate and set up the project structure for the Notes app we will be building. You can do this automatically by running the command below in your &lt;code&gt;tanstack-start-mongodb-notesapp&lt;/code&gt; directory or manually by deleting the example routes (posts, users, etc.) and creating the new folder structure in your code editor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-o&lt;/span&gt; setup.sh https://gist.githubusercontent.com/didicodes/82b5c23647691c4b7b65b1e1558963f5/raw/bbf9d406a82458b236b37652b92212daa1f80f85/setup.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;chmod&lt;/span&gt; +x setup.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ./setup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running the setup script (or completing the manual setup), your project structure should match the one shown below 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhymeofp1lykj7t01fqxc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhymeofp1lykj7t01fqxc.png" alt="IProject structure of the Notes app" width="800" height="686"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creating all the files upfront will make developing the Notes app smoother and give you a clear picture of where each part of the app will live. As you keep reading this tutorial, you'll learn what each file is responsible for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up MongoDB with TanStack server functions
&lt;/h2&gt;

&lt;p&gt;Before building any features, we need to set up MongoDB to work well with TanStack Start and serverless environments. In the next few steps, we'll configure environment variables, define serverless-friendly connection settings, create a reusable MongoDB client, and add type-safe validation so our database layer is efficient and reliable. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Set up environment variables 
&lt;/h3&gt;

&lt;p&gt;Before our app can save or fetch any data, it needs to connect to a database. For this project, we'll use MongoDB Atlas, MongoDB's fully managed cloud database. To connect to it, you need a connection string. Since this connection string includes sensitive information, we'll store it in an environment variable and load it securely at runtime. This keeps our credentials secure and allows us to switch configurations across different environments easily.&lt;/p&gt;

&lt;p&gt;To set this up, go to the &lt;code&gt;.env&lt;/code&gt; file you'd created earlier in your project's folder and add the variables shown below, replacing the value with your MongoDB connection string. To get the connection string, log in to &lt;a href="https://www.mongodb.com/cloud/atlas/register/?utm_campaign=devrel&amp;amp;utm_source=third-party-content&amp;amp;utm_medium=organic_social&amp;amp;utm_content=TanStack+Start+and+MongoDB&amp;amp;utm_term=edidiong.asikpo" rel="noopener noreferrer"&gt;MongoDB Atlas&lt;/a&gt;, create a cluster, then navigate to Connect → Drivers → Node.js, select a version, and copy the displayed connection string. Need additional help getting started with MongoDB Atlas or finding your connection string? Check out the &lt;a href="https://www.mongodb.com/docs/atlas/getting-started/?utm_campaign=devrel&amp;amp;utm_source=third-party-content&amp;amp;utm_medium=organic_social&amp;amp;utm_content=TanStack+Start+and+MongoDB&amp;amp;utm_term=edidiong.asikpo" rel="noopener noreferrer"&gt;MongoDB Atlas Getting Started guide&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# MongoDB Connection String&lt;/span&gt;
MONGODB_URI &lt;span class="o"&gt;=&lt;/span&gt; mongodb+srv://&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;@&amp;lt;cluster&amp;gt;.mongodb.net/&amp;lt;database&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Configure MongoDB settings
&lt;/h3&gt;

&lt;p&gt;TanStack Start's server functions use a serverless execution model, so we have to optimize the connection pool accordingly. To do this, go to the &lt;code&gt;src/config/mongodb.ts&lt;/code&gt; file, copy and add the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Database and collection names&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DB_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notes-app&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;COLLECTION_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Connection pool configuration optimized for serverless&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MONGODB_CONNECTION_CONFIG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="na"&gt;minPoolSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="na"&gt;maxIdleTimeMS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;  &lt;span class="kd"&gt;const&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we've specified our database and collection names and configured a serverless-optimized connection pool. We set minPoolSize to 1 to keep at least one connection warm for faster subsequent requests, and set maxIdleTimeMS to 60000 to close idle connections quickly and free resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Define types with Zod
&lt;/h3&gt;

&lt;p&gt;Before connecting to MongoDB, we need to define our data structures. We'll use Zod for runtime validation and TypeScript for compile-time safety. This will ensure our MongoDB database and the UI of the Notes application receive consistent values. To do this, go to your &lt;code&gt;src/lib/types.ts&lt;/code&gt; file and add the code snippet below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;zod&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ObjectId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mongodb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Zod schemas for input validation
 * These validate data coming from the client
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createNoteSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Title is required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Title must be 200 characters or less&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content must be 10,000 characters or less&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateNoteSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Note ID is required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deleteNoteSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Note ID is required&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * TypeScript types inferred from Zod schemas
 * This ensures our types always match our validation rules
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;CreateNoteInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;createNoteSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;UpdateNoteInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;updateNoteSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;DeleteNoteInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;deleteNoteSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * MongoDB document structure
 * This represents how data is stored in the database
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NoteResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// MongoDB's internal ID&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Client-facing note type
 * This represents how data is sent to the browser
 */&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Note&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ObjectId converted to string&lt;/span&gt;
  &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Date converted to ISO string&lt;/span&gt;
  &lt;span class="nl"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Date converted to ISO string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Document type without _id (for insertOne)
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;NoteDocument&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NoteResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;_id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Converter function: MongoDB document → Client-friendly note
 *
 * This is important because:
 * - ObjectId isn't JSON-serializable
 * - Dates need to be ISO strings for JSON
 */&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;documentToNote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NoteResponse&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Note&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we are using Zod for runtime validation and TypeScript type inference. This gives us both compile-time and runtime type safety.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Create a reusable MongoDB client
&lt;/h3&gt;

&lt;p&gt;TanStack Start executes server functions on the server, so we need a reliable and efficient way to connect to MongoDB. Instead of opening a new database connection on every request, we'll create a shared MongoDB client that can be reused across server function invocations.&lt;/p&gt;

&lt;p&gt;Head back to your code editor and add the code snippet below to the &lt;code&gt;src/lib/mongodb.ts&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MongoClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Collection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Db&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mongodb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;COLLECTION_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;MONGODB_CONNECTION_CONFIG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../config/mongodb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NoteResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MONGODB_URI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MONGODB_URI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Global cache for MongoDB client
 * This survives across serverless function invocations
 */&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CachedConnection&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MongoClient&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Db&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MongoClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Db&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CachedConnection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Get or create a MongoDB connection
 *
 * This is the heart of our serverless optimization.
 * It implements a three-tier caching strategy:
 *
 * 1. Return existing connection if available (fastest)
 * 2. Wait for in-flight connection if one is being created (prevents duplicates)
 * 3. Create new connection if neither exists (slowest, but necessary)
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;connectToDatabase&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MongoClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Tier 1: Return cached connection if available&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Tier 2: Return in-flight connection promise if exists&lt;/span&gt;
  &lt;span class="c1"&gt;// This prevents multiple simultaneous connection attempts&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Validate connection string&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;MONGODB_URI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Missing MONGODB_URI environment variable. &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Please add it to your .env file.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Tier 3: Create a new connection&lt;/span&gt;
  &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MongoClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MONGODB_URI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;appName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;devrel-tutorial-javascript-tanstack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;MONGODB_CONNECTION_CONFIG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;db&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DB_NAME&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Clear promise since we're done&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Reset promise on error to allow retry&lt;/span&gt;
      &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cached&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Get typed collection accessor
 *
 * This provides type-safe access to MongoDB collections.
 * The NoteResponse type ensures we get proper TypeScript
 * autocomplete and type checking.
 */&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getNotesCollection&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NoteResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;connectToDatabase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NoteResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;COLLECTION_NAME&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this in place, our Notes app includes a MongoDB connection layer that integrates efficiently with TanStack Start's server function model. The reusable MongoDB client we've just implemented works well with TanStack Start because it reuses a single MongoDB connection across requests and safely handles concurrent access, thereby avoiding connection pool exhaustion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building server functions for CRUD operations
&lt;/h2&gt;

&lt;p&gt;Now that our database connection layer is in place, let's create server functions for CRUD operations. To create the server functions for our Notes app, go to your &lt;code&gt;src/server/notes.ts&lt;/code&gt; file and add the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createServerFn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@tanstack/react-start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getNotesCollection&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../lib/mongodb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ObjectId&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mongodb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;documentToNote&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;createNoteSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;updateNoteSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;deleteNoteSchema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;NoteDocument&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;NoteResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;~/lib/types&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getNotes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createServerFn&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Note&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getNotesCollection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;docs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;({}).&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;docs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;documentToNote&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error fetching notes:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;failed to fetch notes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createNote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createServerFn&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inputValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;createNoteSchema&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getNotesCollection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;newNote&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NoteDocument&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newNote&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;created&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;insertedId&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Note created but could not be retrieved&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;documentToNote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error creating note:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to create note&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updateNote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createServerFn&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inputValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updateNoteSchema&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getNotesCollection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;updateFields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Partial&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NoteResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;updateFields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;updateFields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOneAndUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$set&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;updateFields&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;returnDocument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;after&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Note not found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;documentToNote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error updating note:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to update note&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deleteNote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createServerFn&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inputValidator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deleteNoteSchema&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getNotesCollection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deleteOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deletedCount&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Note not found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error deleting note:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to delete note&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These functions are created with &lt;code&gt;createServerFn&lt;/code&gt;, which lets us define logic that runs only on the server in TanStack Start. Even though we can call them from the client, the code itself never leaves the server, so database access stays secure. We also use Zod to validate incoming data before it touches the database, and a shared MongoDB client to efficiently reuse connections, which is especially important in serverless environments.&lt;/p&gt;

&lt;p&gt;Before returning data to the client, MongoDB documents are converted into a JSON-safe format, so the UI always receives consistent, serializable data. This approach eliminates the need for separate API routes and manual data fetching, letting you focus on business logic while TanStack Start handles the rest. This is where TanStack Start really shines!&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the UI with real-time updates
&lt;/h2&gt;

&lt;p&gt;With our server functions in place, we can now build the user interface that consumes them. In this step, we'll create the main Notes page, wire it up to our server functions, and ensure the UI stays in sync with the database as users create, update, and delete notes.&lt;/p&gt;

&lt;p&gt;The home route for the app is going to live in &lt;code&gt;src/routes/index.tsx&lt;/code&gt;. This file will define the Notes route and UI and act as the main entry point for displaying and managing notes. Since the implementation is fairly long, I've linked the full file on GitHub instead of pasting it here. So, go to &lt;a href="https://github.com/mongodb-developer/tanstack-start-mongodb-notesapp/blob/main/src/routes/index.tsx" rel="noopener noreferrer"&gt;this GitHub file&lt;/a&gt;, then copy the code and paste it into your &lt;code&gt;src/routes/index.tsx&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;The code you just added uses TanStack Router's &lt;code&gt;loader&lt;/code&gt; to fetch notes on the server before the page renders. That means the initial list of notes is already available when the page loads, giving us fast and server-rendered content by default. On the client side, we keep a local copy of the notes in React state. Whenever a user creates, updates, or deletes a note, we call the corresponding server function (&lt;code&gt;createNote&lt;/code&gt;, &lt;code&gt;updateNote&lt;/code&gt;, or &lt;code&gt;deleteNote&lt;/code&gt;) and then refresh the notes from the database. This gives us instant, real-time updates (instant UI updates driven by server functions) without needing WebSockets or complex state management. The key takeaway here is how TanStack Start allows the UI to communicate directly with server functions, eliminating the need for manual API routes while keeping everything fully type-safe.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxgekg5m5reymsowlbiq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxgekg5m5reymsowlbiq.png" alt="The src/routes/index.tsx file in our Notes app" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The frontend and backend are now connected, so let's see what our Notes app looks like. To do this, run &lt;code&gt;npm run dev&lt;/code&gt; in your terminal and go to &lt;code&gt;http://localhost:3000&lt;/code&gt; in your browser. You should see a form to create new notes, be able to edit and delete notes, and see immediate UI updates when changes are made.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0kd1dd03ukq9chvi5raj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0kd1dd03ukq9chvi5raj.png" alt="Version one of the Notes app built with TanStack Start and MongoDB" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try creating a new note. If everything is set up correctly, it should appear instantly. The data is persisted in MongoDB, and the UI stays in sync automatically thanks to TanStack Start's server functions. Here's what the app looks like with a few notes created 👇&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fac9pmtmse9f0unfyhsma.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fac9pmtmse9f0unfyhsma.png" alt="The full-stack Notes app built with TanStack Start and MongoDB" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing SSR and routing
&lt;/h2&gt;

&lt;p&gt;At this point, we have a fully functional Notes app with server functions handling all database operations. The final step is to configure routing and server-side rendering, which ties everything we've built so far together.&lt;/p&gt;

&lt;p&gt;As you've already seen with route loaders, TanStack Start runs data fetching on the server for the initial request and sends fully rendered HTML to the browser. Subsequent navigations run loaders on the client, call server functions as needed, and update the UI without a full-page reload. This gives us fast first loads, SEO-friendly pages, and smooth client-side navigation by default.&lt;/p&gt;

&lt;p&gt;To configure this, go to your &lt;code&gt;src/router.tsx&lt;/code&gt; and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@tanstack/react-router&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;routeTree&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./routeTree.gen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DefaultCatchBoundary&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/DefaultCatchBoundary&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NotFound&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./components/NotFound&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Create and configure the application router
 */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getRouter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createRouter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;routeTree&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;defaultPreload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;intent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Preload on hover&lt;/span&gt;
    &lt;span class="na"&gt;defaultErrorComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DefaultCatchBoundary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;defaultNotFoundComponent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;NotFound&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;scrollRestoration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Type declaration for full type inference
 */&lt;/span&gt;
&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kr"&gt;module&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@tanstack/react-router&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Register&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;router&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;getRouter&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup gives us file-based routing through the generated routeTree, server-side rendering on the initial page load, and smooth client-side navigation with automatic data fetching. Things like error handling, 404 pages, scroll restoration, and full TypeScript inference all work out of the box and plug directly into the loaders and server functions we set up earlier.&lt;/p&gt;

&lt;p&gt;To confirm that server-side rendering is working, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build
npm run preview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the generated preview URL in your browser, right-click the page, and select "View the page source." There, you should see a fully rendered HTML containing your notes, not just an empty root element. This confirms that your data is fetched on the server and sent as HTML.&lt;/p&gt;

&lt;p&gt;At this point, you have a full-stack application built with TanStack Start and MongoDB. From here, you can build on this foundation by adding authentication, pagination, optimistic updates, or deployment optimizations as your application grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;TanStack Start is pushing full-stack development in a more unified direction, where routing, data fetching, server logic, and rendering all live in the same place and work together naturally. Rather than hiding complexity behind heavy conventions, it gives developers clear, composable building blocks, along with strong performance and end-to-end type safety.&lt;/p&gt;

&lt;p&gt;In this article, we used TanStack Start with MongoDB to build a full-stack Notes app and saw how server functions, loaders, and server-side rendering come together in a real project. MongoDB fits neatly into this setup through server functions, making it a good option for teams that like document-based data models and want explicit control over their backend.&lt;/p&gt;

&lt;p&gt;As the React ecosystem continues to evolve, tools like TanStack Start hint at a future where full-stack development feels simpler, more transparent, and more flexible without sacrificing power or control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaways&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  TanStack Start offers lightweight full-stack development with strong type safety.&lt;/li&gt;
&lt;li&gt;  MongoDB integrates naturally with TanStack Start's server function model using reusable connections.&lt;/li&gt;
&lt;li&gt;  Server functions replace traditional API routes while keeping data access secure.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mongodb</category>
      <category>tanstackstart</category>
      <category>nosql</category>
      <category>react</category>
    </item>
    <item>
      <title>20 Web Monetized Projects to Inspire You</title>
      <dc:creator>Didicodes</dc:creator>
      <pubDate>Wed, 23 Jun 2021 16:07:52 +0000</pubDate>
      <link>https://forem.com/coil/20-web-monetized-projects-to-inspire-you-2k3o</link>
      <guid>https://forem.com/coil/20-web-monetized-projects-to-inspire-you-2k3o</guid>
      <description>&lt;p&gt;Until recently, the only way content creators could make money was through advertising or other business models that take advantage of a user's privacy.&lt;/p&gt;

&lt;p&gt;But with the proposed W3C &lt;a href="https://webmonetization.org/" rel="noopener noreferrer"&gt;Web Monetization API&lt;/a&gt;, creators now have a revenue model that empowers them to make money from their users without advertising, forcing them to subscribe, or invading their privacy. Amazing right? 😍&lt;/p&gt;

&lt;p&gt;There are a ton of developers across the world who are experimenting with Web Monetization. Want to see them? You are in the right place. 😀&lt;/p&gt;

&lt;p&gt;In this article, I collated a list of projects using Web Monetization to make money and offer their users exciting perks.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://cinnamon.video/" rel="noopener noreferrer"&gt;Cinnamon&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FZsSQ_YAKv-y9vFO83kwxSgxlt8vJfF3QGVTuWFLW5dMSFRq_NzJ43dabn1YOMWF2p9ojmGBl6ghVU30RXo5A1LDacp-C6FT5s7pOBXB-B0REK6VZ9WyqyBB3bh4LzpQpG1afTuUb" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FZsSQ_YAKv-y9vFO83kwxSgxlt8vJfF3QGVTuWFLW5dMSFRq_NzJ43dabn1YOMWF2p9ojmGBl6ghVU30RXo5A1LDacp-C6FT5s7pOBXB-B0REK6VZ9WyqyBB3bh4LzpQpG1afTuUb" alt="Cinnamon" width="1600" height="803"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cinnamon is a community-driven content creation platform that allows users to view and create videos while providing native cross-app sharing.&lt;/p&gt;

&lt;p&gt;It uses web monetization to allow video creators to earn from their content without bugging the viewers with unnecessary advertisements.&lt;/p&gt;

&lt;p&gt;With a fee of only $5, Cinnamon grants viewers ad-free access to all videos available on the platform. Then pays the video creators in real-time.&lt;/p&gt;

&lt;p&gt;This means that creators do not have to wait until the end of the month to be paid like traditional video streaming platforms because Cinnamon uses Web monetization to redistribute funds based on the time viewers spend on video content.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://simmer.io/" rel="noopener noreferrer"&gt;Simmer&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FzdVy2Wy53i0gxp4E3c3HdNvlgr-QORDM5W1Woa_duNi9PgD5wpdpzsVTdtFX-aeWN8Qc99UYyVYl9iCerhihqr-aULHHB2YffwjX81fdzl0Fb805MOe_sjefz8yzyTTyG0Z9sfMh" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FzdVy2Wy53i0gxp4E3c3HdNvlgr-QORDM5W1Woa_duNi9PgD5wpdpzsVTdtFX-aeWN8Qc99UYyVYl9iCerhihqr-aULHHB2YffwjX81fdzl0Fb805MOe_sjefz8yzyTTyG0Z9sfMh" alt="Simmer" width="1600" height="890"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simmer is a platform for Indie game developers to host their creations in the browser for free with a single drag and drop mechanism.&lt;/p&gt;

&lt;p&gt;Simmer was one of the first game portals to integrate with the Web Monetization API. Through this integration, creators can &lt;a href="https://community.webmonetization.org/erikad/how-to-create-a-payment-pointer-4joi" rel="noopener noreferrer"&gt;generate their payment pointer from Coil&lt;/a&gt;, paste it into Simmer's game editor UI to make their games monetized automatically.&lt;/p&gt;

&lt;p&gt;If you are a game developer, you should take advantage of the engaging audience on Simmer by uploading your games and making money at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.twitch.tv" rel="noopener noreferrer"&gt;Twitch&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2F01sGuLo4CcYqqfNnntbArfBZCizL6CiwD_IuiwpFjYNqOqI8eXmC5zJ4_tLh8EC9CSyGC8UdZ-35ikVZLEUev5EhY3wkxWGRkVwd87M1jgfIFKSWArbahnrsWk91ifqrOZV1UmaE" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2F01sGuLo4CcYqqfNnntbArfBZCizL6CiwD_IuiwpFjYNqOqI8eXmC5zJ4_tLh8EC9CSyGC8UdZ-35ikVZLEUev5EhY3wkxWGRkVwd87M1jgfIFKSWArbahnrsWk91ifqrOZV1UmaE" alt="Twitch" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Twitch is a live streaming service that allows users to create channels, run broadcasts, and interact with their viewers.&lt;/p&gt;

&lt;p&gt;Thanks to the automatic Web Monetization support on twitch, viewers can support their favorite Twitch Partners and Affiliates by simply watching their streams.&lt;/p&gt;

&lt;p&gt;Then Coil keeps track of how much each streamer has earned and then purchases Twitch Bits when the minimum purchase threshold is reached for that particular streamer. Pretty cool, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://hashnode.com/" rel="noopener noreferrer"&gt;Hashnode&lt;/a&gt; 
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2F8_MEeGJR2jpHAQ9YJgALbRgJuFT0YldQ2cfdjCKyaxfh_0q7QL7t8QvJ7Mb-earNgKJ6KvHf0SlRRptNhPSD-w9shsDls0lEMBMpAXQ-YcjXXP8iUVnM3CK6VRrV3FM6sGhhGhOj" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2F8_MEeGJR2jpHAQ9YJgALbRgJuFT0YldQ2cfdjCKyaxfh_0q7QL7t8QvJ7Mb-earNgKJ6KvHf0SlRRptNhPSD-w9shsDls0lEMBMpAXQ-YcjXXP8iUVnM3CK6VRrV3FM6sGhhGhOj" alt="Hashnode" width="1600" height="927"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hashnode enables developers to create a blog mapped to their domain for free. So they can focus on developing and sharing content on their blogs while we take care of the rest - customization, readership, visibility, web monetization, and so much more.&lt;/p&gt;

&lt;p&gt;As a reader, you'll get access to all the tech articles for free without any ads or restrictions. On the other hand, the creators get to make money based on the amount of time any Coil subscriber spends on their blog.&lt;/p&gt;

&lt;p&gt;Web Monetization has changed a lot of things. Gone are those days where we thought the only way to make money as a blogger was through ads or adding a paywall. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://imgur.com/emerald" rel="noopener noreferrer"&gt;Imgur Emerald&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FzL2HX3nid1NzzpbUA62khyiB7oqE_9q4IaOLr8JcKpJRwPWmdBpUaTL1srkHkL8BqItYbJCAVRBCbkHrrOIU-La1o2Wb4vuApatJD1y9LW_1NWF-9hHdbeslk-tW7Z1qgdq-9p09" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FzL2HX3nid1NzzpbUA62khyiB7oqE_9q4IaOLr8JcKpJRwPWmdBpUaTL1srkHkL8BqItYbJCAVRBCbkHrrOIU-La1o2Wb4vuApatJD1y9LW_1NWF-9hHdbeslk-tW7Z1qgdq-9p09" alt="Imgur Emerald" width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imgur is the easiest way to discover and enjoy the magic of the Internet. It's where you'll find the funniest, most informative, and inspiring images, memes, GIFs, and visual stories served up in an endless stream of bite-sized fun.&lt;/p&gt;

&lt;p&gt;Powered by a passionate community of people worldwide, anyone can join to share cool stuff and vote the best to the top. You'll always find something on Imgur that brightens your day. 😀&lt;/p&gt;

&lt;p&gt;Yes, Imgur uses the Web Monetization API as well. So, Coil will distribute the micropayments to the creators according to the amount of time Coil subscribers spend looking at content on Imgur.&lt;/p&gt;

&lt;p&gt;Subscribers also get access to unlimited uploads, community features, and, most importantly, an ad-free browsing experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.permanent.org/" rel="noopener noreferrer"&gt;Permanent&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2F_XqnQnz9nQZe-ud2PH5jxoGh_7dmDqi5vhmcBFGv7wjx53OSxzPXeAXb2EKSZ_cmiFBRAOYIudnK5sOETGzFLp0PfFO-LvrfGbMkk5ktJG1oXzIvs5CSp3vwKXVJFnqoBbYfnrPR" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2F_XqnQnz9nQZe-ud2PH5jxoGh_7dmDqi5vhmcBFGv7wjx53OSxzPXeAXb2EKSZ_cmiFBRAOYIudnK5sOETGzFLp0PfFO-LvrfGbMkk5ktJG1oXzIvs5CSp3vwKXVJFnqoBbYfnrPR" alt="Permanent" width="1600" height="798"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you ever thought about your digital legacy? By digital legacy, I mean an accumulation of the different text, pictures, and videos you've posted online over the years.&lt;/p&gt;

&lt;p&gt;The truth is our digital legacy is disappearing because we've not had a central place to store it. And each time it disappears, a glimpse of who we were vanishes as well.&lt;/p&gt;

&lt;p&gt;To solve this, Permanent enables you to create, curate, and collaborate on living archives for yourself, your family, and your community.&lt;/p&gt;

&lt;p&gt;Thanks to the power of the Web Monetization API, the owners of Permanent.org are &lt;a href="https://community.webmonetization.org/storagetothepeople/storage-to-the-people-grant-report-1-4idp" rel="noopener noreferrer"&gt;prototyping and building an Open Source API&lt;/a&gt; that allows users to easily store data with a storage provider using a one-time micropayment, with no need for storage provider or frontend service accounts and financial commitments.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.shecodeafrica.org/" rel="noopener noreferrer"&gt;She Code Africa&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F504wiaggft1u9d7obs1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F504wiaggft1u9d7obs1h.png" alt="She Code Africa" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;She Code Africa is a non-profit organization focused on celebrating and empowering young girls and women in tech across Africa.&lt;/p&gt;

&lt;p&gt;They champion exceptional programs and initiatives to improve the tech skills of their members and keep the community engaged, amongst other things.&lt;/p&gt;

&lt;p&gt;She Code Africa recently integrated Web Monetization into their website as a means to earn revenue. This revenue is used to continue the fantastic work they are doing in the developer community. You should &lt;a href="//$ilp.uphold.com/kkd4KdPQwqJM"&gt;support them&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://css-tricks.com/" rel="noopener noreferrer"&gt;CSS-Tricks&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FIqxBn6iKiqtfQksOAAbAJHfr4LcCSxRJR4zkUOLjEbPeYJ4dxaX2rtKGZmt5J4XsxUYJbafCyGfP7Qrjv45otyE3VOPuL6Jx00qkLAAKcUlsPXNApb4zedltpHXmSxoCgO37i-b6" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FIqxBn6iKiqtfQksOAAbAJHfr4LcCSxRJR4zkUOLjEbPeYJ4dxaX2rtKGZmt5J4XsxUYJbafCyGfP7Qrjv45otyE3VOPuL6Jx00qkLAAKcUlsPXNApb4zedltpHXmSxoCgO37i-b6" alt="CSS-Tricks" width="1600" height="891"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;CSS-Tricks is one of the best websites to find insightful articles about frontend development.&lt;/p&gt;

&lt;p&gt;Keeping in mind that it is one of the best websites for frontend content, many devs worldwide have benefitted from it tremendously. Meaning that some of them may have wanted to tip the writers or tell them "thanks" financially.&lt;/p&gt;

&lt;p&gt;With Coil as CSS-Tricks web monetization provider, the website now receives micropayments from readers who have an active Coil subscription and the browser extension.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.ushahidi.com/" rel="noopener noreferrer"&gt;Ushahidi&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FNk0cjREtTGCOWdz-O0AwWw0LXJRSAdpzA8gth12C7YFCPCaeak-sanivRfo2uCvZq5d0oFq_x-FTLSYfqWhavinatamUcSTHnfAD1885SK3L_LI9lWB8cYE_6F0szQ11LPG78f9J" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FNk0cjREtTGCOWdz-O0AwWw0LXJRSAdpzA8gth12C7YFCPCaeak-sanivRfo2uCvZq5d0oFq_x-FTLSYfqWhavinatamUcSTHnfAD1885SK3L_LI9lWB8cYE_6F0szQ11LPG78f9J" alt="Ushahidi" width="800" height="456"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ushahidi is a crowdsource-driven data platform that enables people to raise their voices, inform their decisions, and influence change in their communities.&lt;/p&gt;

&lt;p&gt;Being a non-profit, integrating web monetization on Ushahidi was an excellent way to gain revenue without running ads, especially during the pandemic. So, if any Coil user visits Ushahidi, Coil will calculate the amount of time you've spent on the website and credit the non-profit team. And most importantly, your data is safe!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://akitaproject.site/" rel="noopener noreferrer"&gt;Akita&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FB4dAkTIjEIRedMeJbMNbbZgULoqTWTGV6SMOor0-1W5oxNomY7hjXWQG0ahcfRB9TxBNjHeS_2rdavWU-XCm8AxtMuLu8Cw4T3Ez8WMpUL3SXr11vEFkQ8PxgfoBF2TgW5rSZY0C" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FB4dAkTIjEIRedMeJbMNbbZgULoqTWTGV6SMOor0-1W5oxNomY7hjXWQG0ahcfRB9TxBNjHeS_2rdavWU-XCm8AxtMuLu8Cw4T3Ez8WMpUL3SXr11vEFkQ8PxgfoBF2TgW5rSZY0C" alt="Akita" width="1600" height="1193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Akita is a free and Open Source project that displays your top-visited monetized sites, how much time you're spending on them, and how much you're contributing (or could contribute) to them.&lt;/p&gt;

&lt;p&gt;They also create diverse resources that will help you understand Web Monetization through &lt;a href="https://esse-dev.github.io/a-web-monetization-story/#page-5" rel="noopener noreferrer"&gt;storytelling&lt;/a&gt;, easy-to-use tools, and community outreach.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.pumabrowser.com/" rel="noopener noreferrer"&gt;Puma Browser&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FTvB7uF4UzfAyFljBQ5AOOnvoLFrHKijv314wz4FUy_HbuEcBFNeWTEvWD0saCT3V_JYyQe_tIKGlxcDepI5U_sa6-Y5UbReGo2_TeHbTOH9CxeWWBWMB1zm88XbXJiuyyqRgSfYx" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FTvB7uF4UzfAyFljBQ5AOOnvoLFrHKijv314wz4FUy_HbuEcBFNeWTEvWD0saCT3V_JYyQe_tIKGlxcDepI5U_sa6-Y5UbReGo2_TeHbTOH9CxeWWBWMB1zm88XbXJiuyyqRgSfYx" alt="Puma" width="760" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Puma is a new way to pay for content through a privacy-focused web browser!&lt;/p&gt;

&lt;p&gt;It provides a fast and private mobile Web3 browser that makes it easy to support creators, game &amp;amp; app developers, and charities of your choice.&lt;/p&gt;

&lt;p&gt;The platform uses Coil and the Web Monetization API to create an ad-free user experience and send payment(s) for the content directly from the browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://flood.enclavegames.com/" rel="noopener noreferrer"&gt;Flood Escape&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2F1XFJfrFokdLiLHO1mejqJBE1gcK0n7_P1pMyrbV47B9UWtKwaNar0GyHNKWV2o1Ap8LfB934swSQThz8pUEaJd8k_-g9uN9c0-nnV2M7MII4VKsRxubtqP7jFKUdJQxEoF_cm1vK" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2F1XFJfrFokdLiLHO1mejqJBE1gcK0n7_P1pMyrbV47B9UWtKwaNar0GyHNKWV2o1Ap8LfB934swSQThz8pUEaJd8k_-g9uN9c0-nnV2M7MII4VKsRxubtqP7jFKUdJQxEoF_cm1vK" alt="Flood Escape" width="1600" height="983"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Flood Escape is an action-packed rush to get out of danger!&lt;/p&gt;

&lt;p&gt;You have to build your way up to escape the flood and be rescued in time in the game. You can also customize your experience with flames, get rewarded, and have a good time. 😀&lt;/p&gt;

&lt;p&gt;Flood Escape uses web monetization to generate revenue from its game without the need for bugging users with unnecessary advertisements. They also give web monetization subscribers a bonus of 100 plus coins and a faster cooldown time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://dev.to/"&gt;Dev&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2F_B0ufUB7NjP_DyvwqNT61C2vxhbc8mucx8Jzkyv9R9rzuYGUnm5dEiJsmcYTzkjL1xnDLkHZUQxKmTZW5J3cKNDO-WWMM6TKLhF6uNG_NFY5WOQ50pJ6cN8e1Gnrx1IAeDzPY9zg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2F_B0ufUB7NjP_DyvwqNT61C2vxhbc8mucx8Jzkyv9R9rzuYGUnm5dEiJsmcYTzkjL1xnDLkHZUQxKmTZW5J3cKNDO-WWMM6TKLhF6uNG_NFY5WOQ50pJ6cN8e1Gnrx1IAeDzPY9zg" alt="Dev" width="1600" height="916"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dev is an Open Source software that powers a community of software developers who write articles and build relationships with other developers.&lt;/p&gt;

&lt;p&gt;The platform allows individual authors to add their Coil Payment pointer to their blogs right through their settings. So, every time a Coil subscriber reads your article, micropayments will be sent to your payment wallet by Coil.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://balletrising.com/" rel="noopener noreferrer"&gt;Ballet Rising&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FdK5EXLJNXPgzHo1Ti9GIVSHT4HyMgT52hos3maAtvLmvyojfuMigN8tTXbKstNl061x3xzx2IH0-4UXxrQgDRZr_D9PB9e920O2duP6NOCoyika5GPvufskzn_H7Y5IqNWvX4cxM" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FdK5EXLJNXPgzHo1Ti9GIVSHT4HyMgT52hos3maAtvLmvyojfuMigN8tTXbKstNl061x3xzx2IH0-4UXxrQgDRZr_D9PB9e920O2duP6NOCoyika5GPvufskzn_H7Y5IqNWvX4cxM" alt="Ballet Rising" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ballet Rising is a non-profit organization focused on the stories of people worldwide whose passion for classical ballet is redefining its culture and elevating ballet as a truly global art form.&lt;/p&gt;

&lt;p&gt;It highlights communities where there is an interest in ballet to drive and build positive relationships with local arts organizations so that the global ballet community grows in harmony with local customs.&lt;/p&gt;

&lt;p&gt;Their website is monetized using Coil. So, you can support them by signing up for a coil membership.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://catalins.tech/" rel="noopener noreferrer"&gt;Tech with Catalin&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FEpBX2ilPT-Q4MtE7i-gxYV9TbYX_hf6min5ik8B5QpAHTkkGfmzkWh5kswuOfNrli5GaJlXwG2UNDqQ5QHdFjsBDKqfYwtjxNizudSVKYzOoE8TLzW29n4-x8unrFNF7ffL-h6Gv" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FEpBX2ilPT-Q4MtE7i-gxYV9TbYX_hf6min5ik8B5QpAHTkkGfmzkWh5kswuOfNrli5GaJlXwG2UNDqQ5QHdFjsBDKqfYwtjxNizudSVKYzOoE8TLzW29n4-x8unrFNF7ffL-h6Gv" alt="Tech with Catalin" width="1600" height="1077"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tech with Catalin is a blog owned by Catalin Pit, a Software Engineer specializing in JavaScript technologies and AWS.&lt;/p&gt;

&lt;p&gt;The blog covers content about NodeJS, backend development, Open Source contributions, and growing as a developer.&lt;/p&gt;

&lt;p&gt;Thanks to web monetization, Tech with Catalin generates revenue without displaying ads to its readers or adding a paywall.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.techdirt.com/" rel="noopener noreferrer"&gt;Techdirt&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FLbGSwhRrkOGTJYY0JzarUGQpses3z9gQwjucHe1PhYt5DRmej7GBYtEmA0-CZbL772_wPXB0tlk6wolMWXuCHg7tfmNOHxdap1ZnfBBpu0gyyf6G_PYgbNUa5y9j4axjUfpKRo1u" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FLbGSwhRrkOGTJYY0JzarUGQpses3z9gQwjucHe1PhYt5DRmej7GBYtEmA0-CZbL772_wPXB0tlk6wolMWXuCHg7tfmNOHxdap1ZnfBBpu0gyyf6G_PYgbNUa5y9j4axjUfpKRo1u" alt="Techdirt" width="585" height="86"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Techdirt is an American Internet blog that reports on technology's legal challenges and related business &amp;amp; economic policy issues in the context of the digital revolution. It focuses on intellectual property, patents, information privacy, and copyright reform in particular.&lt;/p&gt;

&lt;p&gt;While other websites have resorted to paywalls, registration requirements, and increasingly annoying/intrusive advertising, Techdirt has made their site open and available to anyone, thanks to Web Monetization.&lt;/p&gt;

&lt;p&gt;As a Coil subscriber, you'll get to support Techdirt anytime you read content on their website.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://onthechain.io/" rel="noopener noreferrer"&gt;On The Chain&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FRUvppvPI3Ur4ALRydCQKUqRgXEzexkips0ySl633aDg-UzX-w2-vLYUUVIGRWjAVKq4KAXPCm9tNA6KzBFX67HbvTliZsMxBKQrTBwkbDF1IYLxZuoC8j0iYKt5w7b6Nyl5-nRRv" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FRUvppvPI3Ur4ALRydCQKUqRgXEzexkips0ySl633aDg-UzX-w2-vLYUUVIGRWjAVKq4KAXPCm9tNA6KzBFX67HbvTliZsMxBKQrTBwkbDF1IYLxZuoC8j0iYKt5w7b6Nyl5-nRRv" alt="On The Chain" width="1600" height="732"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OnTheChain promotes everything cryptocurrency-related. It has many podcasts, Youtube videos, newsletters, and a channel where they share tips and encourage people to join the cryptocurrency community.&lt;/p&gt;

&lt;p&gt;OnTheChain uses the XRP TipBots wallet to receive bits of streaming payments from subscribers via Coil's Web Monetization API.&lt;/p&gt;

&lt;p&gt;This allows them to give their users an incredible ad-free experience and not invade their privacy to make money.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://shortfilmweb.com" rel="noopener noreferrer"&gt;SHORT FILM WEB&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FwG6x5z4v6nPKB7yGpajPEIXusUlYCNN9JLfZcO1cIxJmnMzvp7tbp_0aCR8cN0p8RQa32vQvXTyeYoscryRNu4w-hwmV5JymcERQhSiF6KkDn1PUOmqYdC2OaL0vTQmV28GQZJPf" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FwG6x5z4v6nPKB7yGpajPEIXusUlYCNN9JLfZcO1cIxJmnMzvp7tbp_0aCR8cN0p8RQa32vQvXTyeYoscryRNu4w-hwmV5JymcERQhSiF6KkDn1PUOmqYdC2OaL0vTQmV28GQZJPf" alt="ShortFilmWeb" width="760" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ShortFilmWeb is a directory of some of the best short films freely available online carefully handpicked by the team.&lt;/p&gt;

&lt;p&gt;ShortFilmWeb uses Coil to monetize its content, giving them an edge to continue posting quality films and reviews.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://hackernoon.com/" rel="noopener noreferrer"&gt;Hackernoon&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2F6bvZfDLQVxOlc1x6I6eNOUjsNcjW4ZZ0cx0gv39KUm6SqNcZ7Ri9x4LDxMVc92Rj63ua9Xesav57iOIo46Nsun7UP3yETbdzQA4ZF95eMLIFNxXk2z1bMmiBXjA096M42S9l8ash" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2F6bvZfDLQVxOlc1x6I6eNOUjsNcjW4ZZ0cx0gv39KUm6SqNcZ7Ri9x4LDxMVc92Rj63ua9Xesav57iOIo46Nsun7UP3yETbdzQA4ZF95eMLIFNxXk2z1bMmiBXjA096M42S9l8ash" alt="Hackernoon" width="760" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hackernoon is a community of over 12,000+ contributing writers publishing free high-quality tech stories. The platform supports writers by proofreading their articles before it is published on the platform.&lt;/p&gt;

&lt;p&gt;Hackernoon believes that advertising is not the best way to generate revenue, so they use Web Monetization instead.&lt;/p&gt;

&lt;p&gt;Because of this, writers on the platform can accept a stream of micro-tips from their readers.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://jsbin.com/" rel="noopener noreferrer"&gt;JS Bin&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2F2pHvFXK-XUpNUR9kJfbQRO7EXbmdHuQtCO34KC82ATThvyAS4njEuR3b_n8bLS07E7MMTHaBbZ9BJX35h7OKrmkkrGu80H43BRcSrOFJ_T826jQdfZcHEGw4E2u_FJKSS_0dx83B" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2F2pHvFXK-XUpNUR9kJfbQRO7EXbmdHuQtCO34KC82ATThvyAS4njEuR3b_n8bLS07E7MMTHaBbZ9BJX35h7OKrmkkrGu80H43BRcSrOFJ_T826jQdfZcHEGw4E2u_FJKSS_0dx83B" alt="JS Bin" width="700" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JS Bin is a free and Open Source code-sharing website for web developers. It enables developers to create and share code snippets or web pages with their colleagues or anyone in the developer community.&lt;/p&gt;

&lt;p&gt;Being a free platform, JS Bin uses Coil and the Web Monetization API to generate revenue to keep the website running without ads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Web monetization paves the way for a more open, fair, and inclusive web to better support users and creators.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creators&lt;/strong&gt; make money, and &lt;strong&gt;users&lt;/strong&gt; finally experience their favorite websites without annoying advertisements or the invasion of their privacy.&lt;/p&gt;

&lt;p&gt;Now that you've seen a couple of projects and people using the Web Monetization API by Coil go ahead and become a &lt;a href="https://help.coil.com/docs/membership/get-membership/index.html" rel="noopener noreferrer"&gt;Coil Subscriber&lt;/a&gt; or integrate the &lt;a href="https://webmonetization.org/docs/api/" rel="noopener noreferrer"&gt;Web Monetization API&lt;/a&gt; into your projects, blog, or website. You will find everything you need to get started &lt;a href="https://webmonetization.org/docs/getting-started/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed reading this article. If you have any questions, share them in the comment section below, and I'll reply to every comment. 💛&lt;/p&gt;

</description>
      <category>webmonetization</category>
      <category>coil</category>
      <category>programming</category>
    </item>
    <item>
      <title>TypingDNA Verify - A New Way to Authenticate Users</title>
      <dc:creator>Didicodes</dc:creator>
      <pubDate>Thu, 03 Jun 2021 22:53:23 +0000</pubDate>
      <link>https://forem.com/didicodes/typingdna-verify-a-new-way-to-authenticate-users-5740</link>
      <guid>https://forem.com/didicodes/typingdna-verify-a-new-way-to-authenticate-users-5740</guid>
      <description>&lt;p&gt;Two-factor authentication (2FA) is a security process in which users provide two authentication factors to verify themselves.&lt;/p&gt;

&lt;p&gt;If you think I am referring to the traditional SMS and Email 2FA methods from what you read above, you are wrong. I am actually referring to a more fascinating technology known as typing biometrics. Believe it or not, your typing behavior is unique enough to act as a substitute for traditional second factors. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typingdna.com" rel="noopener noreferrer"&gt;TypingDNA&lt;/a&gt;, a company that provides a free authentication API &amp;amp; managed verification solutions for developers, is a leader in this space - and it’s simple to get started. As the curious developer that I am, I gave &lt;a href="https://www.typingdna.com/verify" rel="noopener noreferrer"&gt;TypingDNA Verify&lt;/a&gt; a try, and I was impressed at the way it was able to verify me through the way I typed. &lt;/p&gt;

&lt;p&gt;In this article, I will tell you everything you need to know about the fascinating TypingDNA Verify and how to use it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65j147ik85tkmkedmya8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65j147ik85tkmkedmya8.png" alt="TypingDNA Verify" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So, what exactly is TypingDNA Verify?
&lt;/h2&gt;

&lt;p&gt;TypingDNA Verify relies on a state-of-the-art authentication engine using AI-based algorithms to verify typing patterns and select the best key phrases that enable higher matching accuracy on short texts. &lt;/p&gt;

&lt;p&gt;This means that your end-users will have to prove their identity by typing generated texts, only deferring to &lt;a href="https://link.springer.com/referenceworkentry/10.1007%2F978-1-4419-5906-5_789#:~:text=Root%20of%20Trust%3A%20A%20system,in%20a%20system%20or%20network." rel="noopener noreferrer"&gt;Root of Trust&lt;/a&gt; channels (SMS &amp;amp; Email) when strictly necessary.&lt;/p&gt;

&lt;p&gt;While SMS OTP’s revolutionized the security best practices decades ago, the method has reached its limits, especially in the fast-paced world that we now live in and tech industries that value good user experience. &lt;/p&gt;

&lt;p&gt;The interesting thing about TypingDNA Verify is that your users can be authenticated without having to search for their phone to see the SMS OTP or use a physical token. Why? That's because users can't forget their fingers or typing behavior behind. 😉  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typingdna.com/verify" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxglaui6rstlmzkop5jh1.png" alt="TypingDNA.png" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With TypingDNA Verify, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recognize trusted users through the way they type.&lt;/li&gt;
&lt;li&gt;Minimize the user's effort and friction while producing a visible sense of protection. &lt;/li&gt;
&lt;li&gt;Catch fraudsters instantly because a true/false match response will be returned instantly and so much more!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most importantly, the chances of a security break are very slim because your typing pattern is unique to only you! &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;At the time of this writing, TypingDNA Verify can only be integrated into a website. However, TypingDNA's Authentication API can be integrated into both a website and mobile application. &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Using TypingDNA Verify on your website
&lt;/h2&gt;

&lt;p&gt;Now that you understand what TypingDNA Verify offers, follow the steps below to integrate it on a website. &lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Create an account
&lt;/h3&gt;

&lt;p&gt;Go to &lt;a href="https://www.typingdna.com/verify" rel="noopener noreferrer"&gt;TypingDNA Verify&lt;/a&gt; and click on the &lt;strong&gt;Sign up to integrate Verify&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwhodo6lym1buqiiisfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvwhodo6lym1buqiiisfh.png" alt="TypingDNA Verify" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sign up with &lt;strong&gt;Google&lt;/strong&gt; or add your &lt;strong&gt;name&lt;/strong&gt;, &lt;strong&gt;email&lt;/strong&gt;, and &lt;strong&gt;password&lt;/strong&gt;, then click on &lt;strong&gt;Continue&lt;/strong&gt;  to proceed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqf6hto3pobm97y45u9q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyqf6hto3pobm97y45u9q.png" alt="Signup on TypingDNA Verify" width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the Client's page, you will be given an option to choose between &lt;strong&gt;Verify&lt;/strong&gt; or the &lt;strong&gt;Authentication API&lt;/strong&gt;. For the purpose of this tutorial, click on Verify to access your &lt;a href="https://www.typingdna.com/clients/" rel="noopener noreferrer"&gt;dashboard&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7k8r1zx47lc00z6ine5x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7k8r1zx47lc00z6ine5x.png" alt="Verify" width="800" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On your dashboard, you will see your &lt;strong&gt;Client ID&lt;/strong&gt; and &lt;strong&gt;Secret&lt;/strong&gt;, a demo of Verify, an option to &lt;strong&gt;set up your first integration&lt;/strong&gt; and &lt;strong&gt;configure your account&lt;/strong&gt; using any of the recommended connection providers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcl195soy3t45iyo96v3z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcl195soy3t45iyo96v3z.png" alt="TypingDNA Dashboard" width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2: Configure your account
&lt;/h3&gt;

&lt;p&gt;Below are the steps required within the dashboard to configure a Verify account before beginning the integration process:&lt;/p&gt;

&lt;p&gt;In order to begin the integration process, you need to configure your account by connecting it to either your &lt;a href="https://www.twilio.com/" rel="noopener noreferrer"&gt;Twillo&lt;/a&gt; and &lt;a href="https://sendgrid.com/" rel="noopener noreferrer"&gt;SendGrid&lt;/a&gt; account.&lt;/p&gt;

&lt;p&gt;Connecting to Twillo or SendGrid is important because they will be used on your behalf to send a verification code or SMS to your users. Without connecting to any of the aforementioned providers, an error message will be returned.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feetige4x7it26tx6su71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feetige4x7it26tx6su71.png" alt="Twillo and Sendgrid" width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the image above implies, click on &lt;strong&gt;Connect Twillo&lt;/strong&gt; if you want your users to receive an SMS verification, then click on &lt;strong&gt;Connect SendGrid&lt;/strong&gt; if you want your users to receive an email verification. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Configuring Twillo and/or Sendgrid serves has a fall-back option for your users. The default 2FA TypingDNA Verify provides is the &lt;strong&gt;typing biometrics&lt;/strong&gt;. 😃 &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 3: Integrate TypingDNA Verify into a website
&lt;/h3&gt;

&lt;p&gt;To kickstart the integration process, click on the &lt;strong&gt;Add your first integration&lt;/strong&gt; button on your dashboard. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdydl6jg4piyvml3ke2eb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdydl6jg4piyvml3ke2eb.png" alt="Add your first integration" width="800" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the name for your application and the domain URL associated with it, then click on the &lt;strong&gt;Create Integration&lt;/strong&gt; button. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xv91fx8db89m0tsrwq2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7xv91fx8db89m0tsrwq2.png" alt="Integrate with TypingDNA" width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This information will be used to ensure proper and secure communication between the &lt;strong&gt;TypingDNA Verify window&lt;/strong&gt; and your &lt;strong&gt;website&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Step 4: Integrate TypingDNA Verify into your codebase
&lt;/h3&gt;

&lt;p&gt;After configuring your account and adding the domain URL of your website to your dashboard, the next thing you need to do is integrate TypingDNA Verify into the frontend and backend of that website.&lt;/p&gt;

&lt;p&gt;Let's get our hands dirty with code! 👇🏽&lt;/p&gt;

&lt;h4&gt;
  
  
  a) Install the TypingDNA Verify client
&lt;/h4&gt;

&lt;p&gt;The first thing you need to do is install the TypingDNA Verify client using the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;typingdna&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;verify&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  b) Initialize the client
&lt;/h4&gt;

&lt;p&gt;After &lt;code&gt;typingdna-verify-client&lt;/code&gt; has been installed successfully, go to your backend code and initialize the client using the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;typingDNAVerifyClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TypingDNAVerifyClient&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
    &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;applicationId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the empty strings with the value of your &lt;code&gt;clientId&lt;/code&gt;, &lt;code&gt;applicationId&lt;/code&gt;, and &lt;code&gt;secret&lt;/code&gt; available on your &lt;a href="https://www.typingdna.com/clients/" rel="noopener noreferrer"&gt;dashboard&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  c) Add the script to your HTML
&lt;/h4&gt;

&lt;p&gt;Now, add the TypingDNA Verify CDN below to your frontend code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://cdn.typingdna.com/verify/typingdna-verify.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script renders the button which opens the &lt;strong&gt;TypingDNA Verify&lt;/strong&gt; window. &lt;/p&gt;

&lt;h4&gt;
  
  
  d) Retrieve the users data
&lt;/h4&gt;

&lt;p&gt;We need to call the &lt;code&gt;getDataAttributes&lt;/code&gt; JavaScript method to pass the credentials and encrypted user data to the &lt;code&gt;button&lt;/code&gt; element we are going to add in our frontend code in the next step.&lt;/p&gt;

&lt;p&gt;So, go back to your backend code and paste the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;typingDNADataAttributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;typingDNAVerifyClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDataAttributes&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
    &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;language&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;mode&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;standard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// 'show_otp' alternatively&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The language and mode are optional parameters, defaulting to ‘EN’ and ‘standard’ respectively.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  e) Add a button element to your HTML
&lt;/h4&gt;

&lt;p&gt;Finally, add a button element with a ‘typingdna-verify’ class and the data attributes that correspond to values of the &lt;code&gt;TypingDNADataAttributes&lt;/code&gt; object explained above. This will be passed to the TypingDNA Verify window once the button is clicked by an end-user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
      &lt;span class="na"&gt;class = &lt;/span&gt;&lt;span class="s"&gt;"typingdna-verify"&lt;/span&gt;
      &lt;span class="na"&gt;data-typingdna-client-id= &lt;/span&gt;&lt;span class="s"&gt;typingDNADataAttributes.clientId&lt;/span&gt;
      &lt;span class="na"&gt;data-typingdna-application-id= &lt;/span&gt;&lt;span class="s"&gt;typingDNADataAttributes.applicationId&lt;/span&gt;
      &lt;span class="na"&gt;data-typingdna-payload= &lt;/span&gt;&lt;span class="s"&gt;typingDNADataAttributes.payload&lt;/span&gt;
      &lt;span class="na"&gt;data-typingdna-callback-fn= &lt;/span&gt;&lt;span class="s"&gt;"callbackFn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; Verify with TypingDNA
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you followed the steps above correctly, your users should now be able to authenticate themselves using TypingDNA Verify.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo 👨‍💻 👩‍💻
&lt;/h2&gt;

&lt;p&gt;You can play around with the &lt;a href="https://verify-demo.typingdna.com/?appId=4a99bca8b982bd6e9b7283da289176c6" rel="noopener noreferrer"&gt;demo here&lt;/a&gt; to get a better understanding of how TypingDNA Verify works and let me know what you think in the comment section.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I believe TypingDNA Verify has a lot of potentials and could be the next big thing in the Two-factor authentication space. So, I'd recommend you give it a try now it is still free for a year. &lt;/p&gt;

&lt;p&gt;Want to learn more about how TypingDNA Verify works? You can access code snippets, demos, and more by visiting their &lt;a href="https://verify.typingdna.com/docs" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed reading this article. If you have any questions, share them in the comment section below, and I'll reply to every comment. 💛  &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>authentication</category>
    </item>
    <item>
      <title>How to Kickstart a Career in Tech</title>
      <dc:creator>Didicodes</dc:creator>
      <pubDate>Fri, 16 Apr 2021 07:42:39 +0000</pubDate>
      <link>https://forem.com/didicodes/how-to-kickstart-a-career-in-tech-cfk</link>
      <guid>https://forem.com/didicodes/how-to-kickstart-a-career-in-tech-cfk</guid>
      <description>&lt;p&gt;A career in tech is a career without boundaries. From web development to product design to project management to app development, the range of job roles and opportunities in the tech ecosystem is huge.&lt;/p&gt;

&lt;p&gt;You might think you're not good enough to have a career in tech -- but give yourself a chance. You can do it.&lt;/p&gt;

&lt;p&gt;The truth is you, don't have to be a genius to work in technology. And in this article, I'll explain how you can kickstart your own career in tech.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do Your Research
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2F8HyjqI1yMiF3BjLOFS7Ajq-_XQTEy5HFKhDoTlsjYOMtD9UEzwxFX5Fb9zteAPlRkz-6FdnRa7FjGaz1PWo_kZ-H0vuEQWB-q1k9tQg8qAAz0Fl6rgCpHUKFkmRWCWKTVQkbIuaX" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2F8HyjqI1yMiF3BjLOFS7Ajq-_XQTEy5HFKhDoTlsjYOMtD9UEzwxFX5Fb9zteAPlRkz-6FdnRa7FjGaz1PWo_kZ-H0vuEQWB-q1k9tQg8qAAz0Fl6rgCpHUKFkmRWCWKTVQkbIuaX" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Technology is a very broad field. This means that there are different areas in tech that require certain skills. In order to discover the right role for yourself, you need to do some research.&lt;/p&gt;

&lt;p&gt;You can start by researching the major areas in tech below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://www.freecodecamp.org/news/beginners-roadmap-web-development/" rel="noopener noreferrer"&gt;Web Development&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.freecodecamp.org/news/what-is-mobile-app-development/" rel="noopener noreferrer"&gt;Mobile Development&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.freecodecamp.org/news/how-to-break-into-product-management-d354944308c0/" rel="noopener noreferrer"&gt;Product Management&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://edidiongasikpo.com/technical-writing-what-and-how" rel="noopener noreferrer"&gt;Technical Writing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.freecodecamp.org/news/how-to-become-a-ux-designer-8f5c8567aefd/" rel="noopener noreferrer"&gt;UI/UX  Designing&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.smashingmagazine.com/2018/01/comprehensive-guide-product-design/" rel="noopener noreferrer"&gt;Product Design&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.freecodecamp.org/news/how-to-become-a-data-scientist-2d829fa33aba/" rel="noopener noreferrer"&gt;Data Science&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After reading through the resources listed above, you will have a better idea of the major areas in tech. With this knowledge, you can go ahead and explore the area that you found most interesting.&lt;/p&gt;

&lt;p&gt;You can either do this online using your favorite search engine or by asking someone in tech (if you know any).&lt;/p&gt;

&lt;p&gt;If you decide to follow the &lt;strong&gt;search engine route&lt;/strong&gt;, ask questions targeted at what you want to discover. For instance, if you want to learn about the benefits of technical writing, your question should follow this format "&lt;em&gt;What are the benefits of becoming a technical writer?&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;If you want to know about the skills required to be a Data Scientist, then your question should follow this format "&lt;em&gt;What do I need to know to become a data scientist?&lt;/em&gt;" or "&lt;em&gt;How do I become a data scientist?&lt;/em&gt;".&lt;/p&gt;

&lt;p&gt;To be honest, it is almost impossible to not find information about the different areas in technology online.&lt;/p&gt;

&lt;p&gt;If you decide to &lt;strong&gt;ask someone in tech, &lt;/strong&gt;always be polite and go straight to the point. Instead of saying "&lt;em&gt;Hi&lt;/em&gt;" and waiting for the person to respond before asking your question, you can follow this format:&lt;/p&gt;

&lt;p&gt;"&lt;em&gt;Hi Rita, my name is Edidiong and I have been researching different career paths in tech. I have read different articles online but I wanted to also hear your opinion as well. How did you know web development was the right career for you? I'd totally understand if you can't respond because of your busy schedule but I will be glad if you do&lt;/em&gt;."&lt;/p&gt;

&lt;p&gt;You might think that this was a pretty long message, but it covered the most important things: your name, what you need, the research you've done already, and that you understand that you are not entitled to the person's time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Decide Which Path to Take
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FSYNgr_JBDmEihWkviF4czVkCAzGvDHff0nujBAxrgEMaCT_lI2K0KWhd3nWLXYQ-2z6-9NYibOhHMvVrI_BBUauaAXhon8KL38C1NHga6FJRimwqYA1KRhgVRzbUsST0Z7U9X7hG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2FSYNgr_JBDmEihWkviF4czVkCAzGvDHff0nujBAxrgEMaCT_lI2K0KWhd3nWLXYQ-2z6-9NYibOhHMvVrI_BBUauaAXhon8KL38C1NHga6FJRimwqYA1KRhgVRzbUsST0Z7U9X7hG" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After carrying out the necessary research, you need to take a moment and decide on the tech career path you want to pursue.&lt;/p&gt;

&lt;p&gt;Perhaps you've read about product design, but you've never had an eye for designing or using colors effectively. Then maybe you also heard about program management and it made you excited because you've always loved managing people or events.&lt;/p&gt;

&lt;p&gt;And maybe your friend in tech also told you about the benefits of being a web developer and you were impressed. But you are not sure yet which tech role to pursue because they all sound good.&lt;/p&gt;

&lt;p&gt;Here are some tips for things to think about when trying to make this decision.&lt;/p&gt;

&lt;h3&gt;
  
  
  Think about your current (transferrable) skills
&lt;/h3&gt;

&lt;p&gt;Before you decided to kickstart a career in tech, you were mostly doing something else that you found interesting. Let's assume you loved painting.&lt;/p&gt;

&lt;p&gt;Anyone who loves to paint understands a lot about colors -- so that means product or UI/UX design might be a good fit for you. The goal here is to try to connect your current skill or hobbies to your proposed tech career path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Just get started -- no matter how that looks
&lt;/h3&gt;

&lt;p&gt;Choosing an initial tech career path doesn't mean that's what your career will always be about. My point is, it is totally fine to start out as a &lt;em&gt;technical writer&lt;/em&gt; and switch to &lt;em&gt;mobile development&lt;/em&gt; later.  &lt;/p&gt;

&lt;p&gt;For instance, I started out as an android developer but eventually switched to web development. So go ahead and get your feet wet before you narrow down to exactly what you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  Go for passion, but be practical too
&lt;/h3&gt;

&lt;p&gt;It is important to know that choosing to pursue a certain tech role because you are passionate about it is great. But it's also ok to choose a role because you believe the opportunities are better, even if you are not very passionate about it.&lt;/p&gt;

&lt;p&gt;So, I'd recommend that you do a mixture of both: choose something you will enjoy doing and become so good that you get tons of opportunities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find Tools &amp;amp; Resources Online
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FS6qSGoWm1gX15RZdsZ9LP06k9fl30j8FS0V61IGaGv2lipJZqIHb8qIoaVieVXCAikk0sZ_bicT_2XuN2tcGBUc-9XM-NoIWa6NCC_bGHdYBbz8oEeLUdV-PEPc6p6G09XzPiStz" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh6.googleusercontent.com%2FS6qSGoWm1gX15RZdsZ9LP06k9fl30j8FS0V61IGaGv2lipJZqIHb8qIoaVieVXCAikk0sZ_bicT_2XuN2tcGBUc-9XM-NoIWa6NCC_bGHdYBbz8oEeLUdV-PEPc6p6G09XzPiStz" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember how I said it is almost impossible not to find resources about tech online? Yes, I wasn't joking.&lt;/p&gt;

&lt;p&gt;It's so amazing that you can also find really insightful resources to kickstart your career in tech for free.&lt;/p&gt;

&lt;p&gt;For instance, freeCodeCamp is a platform that empowers people from all over the world to learn how to code for free. I personally used it while learning how to code and it was one of the best resources. 😃&lt;/p&gt;

&lt;p&gt;To find these tools and resources, search for them on Google by using keywords and phrases like &lt;strong&gt;where can I learn how to be a (insert tech role) for free?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have the funds to acquire paid tools and resources, go for it. If you prefer one on one sessions with a tutor, then you can pay for that, too. 🤑&lt;/p&gt;

&lt;p&gt;Simply put, finding the resource is not an issue. Choosing the right resource is the key thing here.&lt;/p&gt;

&lt;p&gt;So, how do you choose the right project? I'll tell you!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  First, think about your preferred way of learning. For example, do you prefer reading or watching videos?&lt;/li&gt;
&lt;li&gt;  After choosing your preferred learning format, make sure you choose a resource that has some structure. By structure, I mean a plan or curriculum that will educate you about the necessary skills step by step until you understand.&lt;/li&gt;
&lt;li&gt;  Ask questions or read reviews about the resource.&lt;/li&gt;
&lt;li&gt;  Do a quick test run to see if this resource is the right one for you. Does it have the right format, good examples, pictures, and so on?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is very important because choosing the wrong resource or tool might make you give up easily because you won't enjoy the process or understand what you are trying to learn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Just Start Learning
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The secret of getting ahead is getting started. - Mark Twain&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes, I had to share Mark Twain's quote because it is something we all need to remember when we are about to take up a new challenge.&lt;/p&gt;

&lt;p&gt;Deciding to kickstart a career in tech is great, but putting in the necessary work to learn is even greater.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2F8Rc9qF2Hd3-Xt-e83Pd7epL2GfIlFK0dmw6msW8jQqQ4x37ez4CI9E48zni7U7lZzBQfdvaXO6Zcs7J3Zi86Y8C-hDRL3nsIrdy6Zk_WGs3kM_3dPvhtaEfBn9MrsX3rCVJ_6zLf" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh4.googleusercontent.com%2F8Rc9qF2Hd3-Xt-e83Pd7epL2GfIlFK0dmw6msW8jQqQ4x37ez4CI9E48zni7U7lZzBQfdvaXO6Zcs7J3Zi86Y8C-hDRL3nsIrdy6Zk_WGs3kM_3dPvhtaEfBn9MrsX3rCVJ_6zLf" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Think about it this way: you did your research about different roles in tech, you chose your preferred tech career path, and you found the right learning resources. But now you don't want to put in the work and learn? No!&lt;/p&gt;

&lt;p&gt;You didn't spend all that time and effort to give up at the most important point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You have to start learning.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Set up a schedule that works for you. For instance, learning for at least 30 minutes or 1 hour every day. If you have more time, then spend more time learning. Your growth will be tremendous.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build projects
&lt;/h2&gt;

&lt;p&gt;Once you have a good foundation of knowledge, start building basic projects.&lt;/p&gt;

&lt;p&gt;Most people think they need to know everything about a particular programming language or tool before they start building a project. But most times, this only results in watching tutorials for months.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FSEN5atLOM4n8zIUHuslTJ69p37kvdNdOFVKzpbQMHg-4Y278Sk2JXQmVcdQQgbPw9sJajbMl7OUcgjeHX82U14Z6ShblA2Fg3kkYs3JFXx7LV7DZdhiExMMMOR8nx_Ro1l2OB58A" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2FSEN5atLOM4n8zIUHuslTJ69p37kvdNdOFVKzpbQMHg-4Y278Sk2JXQmVcdQQgbPw9sJajbMl7OUcgjeHX82U14Z6ShblA2Fg3kkYs3JFXx7LV7DZdhiExMMMOR8nx_Ro1l2OB58A" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The truth is that building projects lets you improve your coding skills in ways you can't imagine. It also gives you something to show off in interviews when you are telling your interviewers about your tech skills.&lt;/p&gt;

&lt;p&gt;Here's a list of beginner-friendly projects ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;a href="https://codinginflow.com/app-ideas-learn-android-programming" rel="noopener noreferrer"&gt;9 Simple App Ideas to Learn Android Programming (With Tutorials).&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.freecodecamp.org/news/more-project-ideas-to-improve-your-coding-skills-99f48d09bb4b/" rel="noopener noreferrer"&gt;Project ideas to help you improve your coding skills&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="http://www.webtrainingcentre.com/ux-design-projects-beginners/" rel="noopener noreferrer"&gt;UX Design Projects for Beginners.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.upgrad.com/blog/web-development-project-ideas-for-beginners/" rel="noopener noreferrer"&gt;21 Interesting Web Development Project Ideas For Beginners [2020].&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://www.pinterest.com/ReidSchlegel/product-design/" rel="noopener noreferrer"&gt;500+ Product Design ideas in 2020.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://blog.moeminmamdouh.com/7-websites-to-find-front-end-projects-for-your-portfolio" rel="noopener noreferrer"&gt;7 Websites To Find Front End Projects For Your Portfolio.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;a href="https://blog.greenroots.info/how-to-find-blog-content-ideas-effortlessly-ckghrjv5200o7rhs1ewn40102" rel="noopener noreferrer"&gt;How to find blog content ideas effortlessly?&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Start writing
&lt;/h2&gt;

&lt;p&gt;Most people think you have to be super smart to start writing and sharing knowledge. But I completely disagree. As much as we write to share knowledge, we also write to document what we've learned.&lt;/p&gt;

&lt;p&gt;Our brains don't have the capacity to remember everything we've learned, so writing it down on your blog will serve as a reference point for you in the future. It can also help someone who is also trying to understand that concept you just learned.&lt;/p&gt;

&lt;p&gt;In my case, I created my &lt;a href="http://edidiongasikpo.com/" rel="noopener noreferrer"&gt;blog&lt;/a&gt; with &lt;a href="https://hashnode.com/@didicodes/joinme" rel="noopener noreferrer"&gt;Hashnode&lt;/a&gt; because it is super fast, has a strong community, and allows you to map the blog to your domain. I'd recommend you use the same platform for creating your first blog.&lt;/p&gt;

&lt;p&gt;After you've gotten comfortable with writing, you can now submit your articles to &lt;a href="http://freecodecamp.org/" rel="noopener noreferrer"&gt;freeCodeCamp's&lt;/a&gt; publication to reach a wider audience and give back to the tech community or republish your articles on DEV. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2Fk5IRNKiSFBUQt_Q1aH1iklNFDYTm9RbWOd1hB3LakyH7Tgzm8eDjVtqC6vVKphtfEEPc6yXqsrKOf4D6sGV2Nrn3aPshdsd8z87QvqBGpkqxWu3vnB9HWNd1_UQtym66stvdGWSq" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh3.googleusercontent.com%2Fk5IRNKiSFBUQt_Q1aH1iklNFDYTm9RbWOd1hB3LakyH7Tgzm8eDjVtqC6vVKphtfEEPc6yXqsrKOf4D6sGV2Nrn3aPshdsd8z87QvqBGpkqxWu3vnB9HWNd1_UQtym66stvdGWSq" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Writing is a great way to digest and process the information you take in. It gives you access to so many opportunities and can also help you make your mark in the tech ecosystem.&lt;/p&gt;

&lt;p&gt;Writing changed my life, and I believe it will be of great help to you and your tech career. &lt;a href="https://hashnode.com/@didicodes/joinme" rel="noopener noreferrer"&gt;Start blogging now&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stay consistent
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2F0HbPtWXfDHBYwngCGal0IOmdrn9nyGKcNB3IGaxUtKSGkQ2Y315lRZtM3XmoFcwKMY_rUWyQVlBqw6mr2Vug6DrLUCSGdXkmdY7OhZOkJ_2w-jwLgWASsYbAVCYjRpPvZcuwzkiV" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Flh5.googleusercontent.com%2F0HbPtWXfDHBYwngCGal0IOmdrn9nyGKcNB3IGaxUtKSGkQ2Y315lRZtM3XmoFcwKMY_rUWyQVlBqw6mr2Vug6DrLUCSGdXkmdY7OhZOkJ_2w-jwLgWASsYbAVCYjRpPvZcuwzkiV" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the most important step in kick-starting a career in tech. It's highly unlikely you'll achieve great things if you're not consistently trying to improve on your chosen tech skill.&lt;/p&gt;

&lt;p&gt;Consistency forms habits that become almost second nature. So if you code or design for at least 30 minutes every day for a month, you will become better and better.&lt;/p&gt;

&lt;p&gt;It is not compulsory to stick with the 30 minutes scenario above -- just find out what works for you, and be very consistent. Only then will the sky be your limit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Kickstarting a career in tech is definitely doable if you follow these steps. And I strongly encourage you to try, because of the diverse opportunities that come with it.&lt;/p&gt;

&lt;p&gt;Anybody who is willing to learn can start a career in tech with or without any formal knowledge from school. Just go ahead and start.&lt;/p&gt;

&lt;p&gt;Yes, it may not be really easy, but there are so many supportive tech communities willing to help you through.&lt;/p&gt;

&lt;p&gt;I hope you learned a thing or two from this article. If you have any questions, feel free to send me a &lt;a href="https://twitter.com/Didicodes" rel="noopener noreferrer"&gt;DM on Twitter&lt;/a&gt; and I'll be happy to answer every single one.&lt;/p&gt;

</description>
      <category>career</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>The Importance of Blogging as a Developer</title>
      <dc:creator>Didicodes</dc:creator>
      <pubDate>Sun, 11 Apr 2021 16:44:43 +0000</pubDate>
      <link>https://forem.com/didicodes/the-importance-of-blogging-as-a-developer-358</link>
      <guid>https://forem.com/didicodes/the-importance-of-blogging-as-a-developer-358</guid>
      <description>&lt;p&gt;Aside from being able to educate others, blogging is also a really great way to reinforce knowledge, build your brand, earn money, amongst other things.&lt;/p&gt;

&lt;p&gt;Most developers shy away from blogging because they think they are not smart enough or they don't think it is important.&lt;/p&gt;

&lt;p&gt;As someone who has been into tech blogging for quite some time, I will be sharing some reasons why blogging is important for developers. If you've ever wondered why developers should blog, then this article was written with you in mind. I do hope you learn a thing or two from it.&lt;/p&gt;

&lt;p&gt;Now let's get right into it. 💃🏽&lt;/p&gt;

&lt;h2&gt;
  
  
  Give back to the community
&lt;/h2&gt;

&lt;p&gt;When you started learning how to code, you most likely read a couple of tech articles to grasp that programming language. You know what? Let's scratch that. You still read tech articles now that you are no longer a code newbie. &lt;/p&gt;

&lt;p&gt;If the assumption I made above is correct, that means you've benefited from at least 1 tech blogger in the developer community at some point in your career.  So, why not write to help another developer too? &lt;/p&gt;

&lt;p&gt;There's a high chance that this might not seem like an excellent reason for you to start blogging but try to imagine those articles that helped you out were not written by the authors and ask yourself if you would've been able to understand those tech concepts at the time. &lt;/p&gt;

&lt;p&gt;Blogging gives you an opportunity to give back to the community, to help someone understand coding, and to inspire.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improve your skill
&lt;/h2&gt;

&lt;p&gt;Over the years, I have noticed that people think tech blogging is only about educating others. But that's not true. I believe blogging actually helps the author as much as it helps the reader. &lt;/p&gt;

&lt;p&gt;Truth be told, most tech bloggers actually research the tech concepts days or weeks before writing an article about it on their blog. Because of this research carried out by tech bloggers, their knowledge about everything they write about keeps improving. For instance, if I write about ReactJS consistently for a year, I will be way better at ReactJS than I was the previous year when I didn't write anything about it. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, what exactly am I saying?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Blogging helps to educate others, but it will help you learn about new things and improve your coding and communication skills.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build your brand
&lt;/h2&gt;

&lt;p&gt;At first, it may seem like nobody is watching or noticing your articles. But over time, people will get to know you for the type of tech articles you write. And that, my friend, is a good way to build your brand.&lt;/p&gt;

&lt;p&gt;Blogging about a certain programming language or tech concept consecutively will make you known in that respective developer community. This can lead to recommendations, opportunities, job offers, and so much more.&lt;/p&gt;

&lt;p&gt;When recruiters see your blog posts, it can also increase your chances of getting the job over others who don't write technical articles because it shows them you are really knowledgeable about the subject matter and you also have good communication skills. I mean, who doesn't love a developer with strong communication skills? 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  Make money
&lt;/h2&gt;

&lt;p&gt;Oh yes, you can make money from blogging. In fact, it is such a good way to make a passive income even while working as a full-time developer. &lt;/p&gt;

&lt;p&gt;Listed below are some ways to make money while blogging as a developer;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Ads:&lt;/strong&gt; Adding ads to your blog is one of the most popular ways to make money through tech blogging. But most developers don't like seeing a lot of ads when they are reading articles, so I will recommend using &lt;a href="https://www.carbonads.net/" rel="noopener noreferrer"&gt;Carbon Ads&lt;/a&gt; because it centered around content for developers and designers, so developer may not leave your blog when they see these type of ads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web monetization:&lt;/strong&gt; If you are not a fan of ads, you can integrate &lt;a href="https://x.hashnode.dev/web-monetization-on-hashnode-ckdu9umr900jmn0s1gr0r4gis" rel="noopener noreferrer"&gt;Web Monetization&lt;/a&gt; on your blog.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Paid community writing programs:&lt;/strong&gt; There are tons of tech companies and communities that pay developers to write technical articles for them. Most of them pay between 100 to 2000 dollars. Here's a list of some &lt;a href="https://github.com/malgamves/CommunityWriterPrograms" rel="noopener noreferrer"&gt;paid community writing programs&lt;/a&gt; for developers. &lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Affiliate links:&lt;/strong&gt; You can add &lt;a href="https://ahrefs.com/blog/affiliate-marketing/" rel="noopener noreferrer"&gt;affiliate links&lt;/a&gt; from various tech companies on your blog posts. &lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Community funding:&lt;/strong&gt; Getting community funding is also another way to make money as a tech blogger. With a &lt;a href="https://www.patreon.com/" rel="noopener noreferrer"&gt;Patreon&lt;/a&gt; or &lt;a href="https://www.buymeacoffee.com/" rel="noopener noreferrer"&gt;Buy Me a Coffee&lt;/a&gt; account, various people in the developer community can support you financially monthly.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Blogging is a combination of sharing &amp;amp; gaining knowledge. It can help you achieve great things &amp;amp; get better as a developer. &lt;/p&gt;

&lt;p&gt;My final words would be to remind you that tech bloggers have the great benefit of becoming lifelong learners because they need to be well-versed in the field they are writing to explain the concepts to readers clearly. So when you blog, you also help yourself too. &lt;/p&gt;

&lt;p&gt;If you now see why you should start blogging and want to get started, I'd recommend using &lt;a href="https://hashnode.com/@didicodes/joinme" rel="noopener noreferrer"&gt;Hashnode&lt;/a&gt; because it can help you spin up a blog mapped to your custom domain in under 2 minutes. Aside from that, you'll also get readership from the dev community, own a newsletter service, an audio version of your articles, and more! &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Having a blog mapped to your custom domain is very important for your personal brand and SEO. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Do you know of any other benefits of blogging as a developer? Please share it in the comment section below, and I'll reply to every comment.&lt;/p&gt;

</description>
      <category>developers</category>
      <category>blogging</category>
      <category>devcommunity</category>
    </item>
    <item>
      <title>Top 10 Virtual Confs Every DEV must attend in April 2021</title>
      <dc:creator>Didicodes</dc:creator>
      <pubDate>Wed, 24 Mar 2021 11:36:39 +0000</pubDate>
      <link>https://forem.com/didicodes/top-10-virtual-confs-every-dev-must-attend-in-april-2021-246l</link>
      <guid>https://forem.com/didicodes/top-10-virtual-confs-every-dev-must-attend-in-april-2021-246l</guid>
      <description>&lt;p&gt;As a developer, attending events or conferences can broaden your horizon, expand your network, strengthen your existing skillset, and more!&lt;/p&gt;

&lt;p&gt;Different communities and companies host tech events every year to help developers become better in their respective fields. Due to this, finding the right event to attend can be a bit tasky. &lt;/p&gt;

&lt;p&gt;To help you find the right event to attend in April, I compiled the top 10 developer-focused conferences/events happening in April 2021 for you. 👇🏽&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;a href="https://remote.reactsummit.com/" rel="noopener noreferrer"&gt;React Summit&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://remote.reactsummit.com/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmt8gfftxjw11ug711g8g.png" alt="React Summit" width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;React Summit is the biggest React conference online! Each day will feature talks from different amazing speakers across the world. Besides the talks and hands-on React workshops, you can expect excellent MCs, virtual networking rooms focusing on tech topics, interactive entertainment, engaging challenges for all participants, and more! You don't want to miss &lt;a href="https://remote.reactsummit.com/" rel="noopener noreferrer"&gt;this conference&lt;/a&gt; if you are a React developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;a href="https://hashnode.com/bootcamp/batch-3" rel="noopener noreferrer"&gt;Hashnode Bootcamp III&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://hashnode.com/bootcamp/batch-3" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fokw6bglzqoyawjb6yot4.png" alt="Hashnode Bootcamp III" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a developer, building a personal brand can help you boost your career, access opportunities &amp;amp; more. This bootcamp aims to remove all the fuss around building a personal brand as a developer — from having a healthy open source profile to maintaining an influential developer blog, showing your work online, and more! Want to build or improve your personal brand? &lt;a href="https://hashnode.com/bootcamp/batch-3" rel="noopener noreferrer"&gt;Register for this event&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. &lt;a href="https://dev.events/conferences/vueconf-us-online-2021" rel="noopener noreferrer"&gt;Vue Conference&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.events/conferences/vueconf-us-online-2021" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvcebbqmfx25mz4nbux08.png" alt="Vue Conference" width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This year's VueJS Conference will be happening virtually because of the pandemic. But that doesn't mean it won't still be amazing! If you use VueJS or want to start using it, this conference should be a must-attend for you because the speakers are some of the best VueJS developers. &lt;a href="https://dev.events/conferences/vueconf-us-online-2021" rel="noopener noreferrer"&gt;Learn more and register&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. &lt;a href="https://devternity.com/" rel="noopener noreferrer"&gt;DevTernity&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://devternity.com/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fugo0igxmayjc09g42ic3.png" alt="DevTernity" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DevTernity is one of the top 3 international software development conferences in Europe. &lt;/p&gt;

&lt;p&gt;Unlike other conferences, DevTernity focuses on the core skills paramount to your success – coding, architecture, and leadership.&lt;/p&gt;

&lt;p&gt;Attending this conference will give you an uncompetitive advantage as you start your journey towards becoming a Software Architect, Engineering Lead, or CTO. The tickets are very limited so grab one &lt;a href="https://devternity.com/" rel="noopener noreferrer"&gt;now&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  5. &lt;a href="https://dev.events/conferences/developer-week-europe-online-2021" rel="noopener noreferrer"&gt;Developer Week Europe - Online DevOps, Cloud, and API conference&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.events/conferences/developer-week-europe-online-2021" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6k17eghxjc6nsqf8pkx.png" alt="Europe Online" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This virtual event is set to be one of the biggest in Europe. It will cover talks ranging from DevOps, cloud, APIs, and more. The lineup of speakers is fantastic. PS: You don't have to be in Europe to attend this event because it is virtual. So, register, attend and thank me later. 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  6. &lt;a href="https://conf.strapi.io/" rel="noopener noreferrer"&gt;Strapi Conf&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://conf.strapi.io/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpuqnpyghr594h73atls.png" alt="image.png" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://strapi.io/" rel="noopener noreferrer"&gt;Strapi&lt;/a&gt; is the next-gen headless Open Source CMS enabling content-rich experiences to be created, managed, and exposed to any digital device. The team is hosting its first-ever conference this year in April. Do check it out if you are a Strapi.js developer or enthusiast. &lt;/p&gt;

&lt;h2&gt;
  
  
  7. &lt;a href="https://www.writethedocs.org/conf/portland/2021/" rel="noopener noreferrer"&gt;Write the Docs Portland&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.writethedocs.org/conf/portland/2021/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzj8gq2t4nw8m84p9eozo.png" alt="Write the Docs Portland" width="800" height="353"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Write the Docs brings everyone who writes the docs together in the same room: Programmers, Tech Writers, Support, Designers, Developer Advocates, and more. If you want to improve your writing skill or meet like-minded people who love good documentation, &lt;a href="https://www.writethedocs.org/conf/portland/2021/" rel="noopener noreferrer"&gt;this conference is for you&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. &lt;a href="https://serverless-architecture.io/thehague" rel="noopener noreferrer"&gt;Serverless Architecture Conference&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://serverless-architecture.io/thehague" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fby10nl9c02pnc2qwbasz.png" alt="Serverless Architecture Conference" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This conference will help you master Cloud-Native architectures, the Kubernetes Ecosystem, and Functions. The speakers, topics, and organizers are top-notch.  The Serverless ecosystem keeps growing tremendously, and I think this is a great event for anyone interested in all things Serverless.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. &lt;a href="https://azurelive.nl/" rel="noopener noreferrer"&gt;AzureLive&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://azurelive.nl/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F33ulmti56j9j2dvhwvhm.png" alt="image.png" width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AzureLive is a brand new, single-day event that will feature some of the best speakers and content the Azure community has to offer. The speakers will speak on Architecture, DevOps, Governance, Security, Serverless, AKS, AI, and many more will be discussed on that day. &lt;/p&gt;

&lt;p&gt;Besides technical talks, there will also be some IT Professional talks and Real-life Azure stories and examples. &lt;/p&gt;

&lt;h2&gt;
  
  
  10. &lt;a href="https://jsheroes.io/" rel="noopener noreferrer"&gt;JS Heroes&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://jsheroes.io/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F08699il2wrw48sslojbr.png" alt="image.png" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JS Heroes is an Open Source community event centered around front-end development. Love open source events? This is a great one to attend in April. &lt;/p&gt;




&lt;p&gt;Thanks for reading up to this point. I hope you discovered an amazing event to attend in April. 😀&lt;/p&gt;

</description>
      <category>techtalks</category>
      <category>javascript</category>
      <category>conferences</category>
      <category>developers</category>
    </item>
    <item>
      <title>Open Source Contributions: A catalyst for growth.</title>
      <dc:creator>Didicodes</dc:creator>
      <pubDate>Wed, 05 Feb 2020 09:53:50 +0000</pubDate>
      <link>https://forem.com/didicodes/open-source-contributions-a-catalyst-for-growth-38il</link>
      <guid>https://forem.com/didicodes/open-source-contributions-a-catalyst-for-growth-38il</guid>
      <description>&lt;p&gt;Sometimes learning from other people’s experiences builds a certain level of certainty as to what we are doing right and what we may have done wrong. This is because it is very easy to learn from their experiences and build on them. In this article, I will use my personal experience (my Open Source story) to explain why I believe making open source contributions is a catalyst for growth and I hope it gives you the push to create your first &lt;a href="https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests" rel="noopener noreferrer"&gt;pull request.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How did I get started?
&lt;/h2&gt;

&lt;p&gt;Well, my first attempt to make an Open Source contribution was sometime in March 2018. At that time, I just found out about the &lt;a href="https://summerofcode.withgoogle.com/" rel="noopener noreferrer"&gt;Google Summer of Code (GSOC) program&lt;/a&gt; from Samson Goddy and I told myself, “oh well, I think it’s time to apply what I learned on Android development during my industrial training late 2017 at Start Innovation Hub to a real life project”. I went to the GSOC site and glanced through all the organizations and their respective projects and the &lt;a href="https://opendatakit.org/" rel="noopener noreferrer"&gt;Open Data Kit&lt;/a&gt; organization caught my attention.&lt;br&gt;
To participate in the Google Summer of Code program, you have to be a student in the university and also make at least one contribution to the organization. I was already in the university, so all I had to do was to make at least one contribution to an organization before submitting my proposal. When I first joined the Open Data Kit slack channel, I was intimidated and overwhelmed but most open source organizations label issues on their repositories so it was easy to find the right issue to solve. As a beginner at the time, I jejely glanced through the beginner-friendly issues and decided to work on an issue titled &lt;a href="https://github.com/opendatakit/collect/pull/2045" rel="noopener noreferrer"&gt;Escape markdown characters using backslashes&lt;/a&gt;. This task entailed writing code to enable the ODK Collect app support escaping markdown characters using a backslash and this could be achieved using regular expressions (Regex).&lt;/p&gt;

&lt;h2&gt;
  
  
  My First Pull Request
&lt;/h2&gt;

&lt;p&gt;Honestly, I never knew about regular expressions before I decided to work on that issue, I didn't even know it existed, which meant I had to do a lot of research. You probably won’t believe me if I told you it took over 3 weeks for the pull request to be merged because the mentor ensured that I understood what I was trying to do, the implications of making those changes and most importantly that the code I wrote adhered to the coding standards of the organization.&lt;/p&gt;

&lt;p&gt;Working on the issue took me from not understanding anything about regex to getting my first pull request merged by the Open Data Kit open source organization and &lt;em&gt;mehn&lt;/em&gt;, this was literally the best feeling. The thought that you’ve contributed to an application that is used by thousands of people across the world and that &lt;strong&gt;someone somewhere&lt;/strong&gt; is currently benefiting from that feature you improved is so fulfilling. It was truly an overwhelming but interesting first Pull Request.&lt;/p&gt;

&lt;p&gt;After I had successfully made a contribution to the organization, all I had to do was to submit a proposal describing the project I wanted to work on and why I felt I was the best candidate for the project; this was another good thing to learn because I had never written a proposal in my life. I eventually created a proposal and submitted it for review. Unfortunately, when the accepted candidates were announced, I wasn’t accepted.&lt;/p&gt;

&lt;p&gt;This wasn’t a sad moment for me because I suspected that someone with more experience would be selected for the project but I was super grateful that I learned a lot about writing proposals, contributing to open source, writing a good commit message and raising a good pull request. So I saw it as a win-win situation.&lt;/p&gt;

&lt;h2&gt;
  
  
  My second Open Source project, well I thought it was…
&lt;/h2&gt;

&lt;p&gt;After I graduated from school in August 2018, I decided to give Open Source contributions another try by applying for the Outreachy internship to an organization called &lt;a href="https://www.wikimedia.org/" rel="noopener noreferrer"&gt;Wikimedia&lt;/a&gt; and my role there was to improve the MediaWiki Action API and also write sample codes in Python which was a great opportunity to learn not just as a developer but as a technical writer. Making contributions to the Mediawiki organization was not as difficult as my first pull request because I had already submitted a pull request before. If you ask me, I think I was &lt;em&gt;killing it&lt;/em&gt; during this application phase.&lt;br&gt;
A few days to the deadline for submitting my proposal, I had to travel to Taraba state via Enugu for &lt;a href="https://www.nysc.gov.ng/" rel="noopener noreferrer"&gt;NYSC&lt;/a&gt;; however, I missed my bus that morning because I was trying to fix an issue with the pull request I submitted. When this happened, I told myself that I was definitely going to be accepted, afterall, I missed my bus because of it. But I wasn’t selected for the internship. This time around, I was deeply sad because I thought I did better than other applicants. The rejection broke me to the point were I said I wasn’t going to make open source contributions again.&lt;/p&gt;

&lt;p&gt;Well, thinking about it now, I guess I should have started with unpaid Open Source contributions first to build myself instead of jumping directly into applying for paid Open Source internship opportunities.&lt;/p&gt;

&lt;h2&gt;
  
  
  My failed applications start to pay off
&lt;/h2&gt;

&lt;p&gt;In January 2019, &lt;a href="https://www.outreachy.org/" rel="noopener noreferrer"&gt;Outreachy&lt;/a&gt; announced that they were accepting proposals for the internship. Lo and behold, the same project I had applied for in the previous round in 2018 was among the projects and I felt I had a better chance of getting accepted since I had worked on this project before. As usual, I made contributions to the organization and submitted a proposal during the application phase. At this time, I was also looking for a company to serve during my NYSC in Lagos and I applied to a couple of companies and went to different interviews. One interesting thing I will love to point out in this article was my interview with a company called Interswitch. During the second phase of my interview with Interswitch, I met with the CIO and during our interaction, I spoke about my experience with making open source contributions and how I was currently writing sample codes and improving API documentation. The CIO asked me about the last time I made a contribution to the organization and luckily for me, I actually made a contribution to Mediawiki that morning before I went for the interview &lt;strong&gt;so with a smile on my face I told him “today”&lt;/strong&gt;. He went further to ask which API I worked on and as I explained the workings of the API to him, I noticed he was impressed. It turned out that Interswitch was looking for someone with that skill at that time so there was a match. I got hired primarily because of my experience with writing sample codes, improving the API docs for the MediaWiki and of course, the ability to code.&lt;/p&gt;

&lt;p&gt;Sadly, when the results for accepted interns were announced by Outreachy, I wasn't selected. It was a bittersweet experience because I had gained a lot of experience from making those contributions and also got accepted as a Software Engineer at an amazing company for my NYSC.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finally the big W - Google Season of Docs
&lt;/h2&gt;

&lt;p&gt;I refused to be fazed by the disappointments I had with my previous applications so I decided to give it a shot again, this time I applied for Google’s Season of Docs with the &lt;a href="https://www.videolan.org/" rel="noopener noreferrer"&gt;VideoLAN organization&lt;/a&gt;. The VideoLAN organization owns the &lt;a href="https://www.videolan.org/vlc/" rel="noopener noreferrer"&gt;VLC media player&lt;/a&gt; which has been downloaded over 3 billion times. When you think of the fact that there are over 7 billion people in the world right, it means that means almost half of the people in the entire world must have downloaded VLC into either their phones or desktop. Blown!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Again&lt;/strong&gt;, I researched about the project, what it entailed, wrote a proposal and submitted it to Google and guess what? My proposal was accepted. I think I literally almost threw my laptop away when I got the email from Google. It was a surreal moment for me. I have literally been using the VLC media player since I was in secondary school and the fact that I was going to work for this organization was mind blowing.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Contributing to Open Source organizations opens you up to a lot of opportunities and connects you with people doing amazing things all over the world. Who would have thought that I would get an opportunity to work as a technical writer for an organization that I have been using their product since secondary school and get paid 3000$ to do it, or get to have meetings and conversations with the president of the VideoLAN organization or get to do my NYSC at Interswitch or even get to speak at events about the beauty of Open Source?&lt;/p&gt;

&lt;p&gt;To sum it up, I successfully completed the &lt;a href="https://developers.google.com/season-of-docs/docs/participants" rel="noopener noreferrer"&gt;Season of Docs program&lt;/a&gt; by Google in November and also got a full-time job as a Developer Relations at Interswitch in December and without any doubt in my heart, I can boldly say that &lt;strong&gt;OPEN SOURCE CONTRIBUTIONS&lt;/strong&gt; strongly contributed to my growth as a Software Engineer and Technical Writer.&lt;/p&gt;

&lt;p&gt;Yes, it is a &lt;strong&gt;catalyst for growth&lt;/strong&gt; and you absolutely do not have to jump right into applying for paid remote open source internships like I did if you are not ready for that, you can start by submitting an issue, fixing an already existing issue, correcting a typo, making a pull request to an organization, creating an Open Source project, joining the &lt;a href="https://oscafrica.zulipchat.com/" rel="noopener noreferrer"&gt;Open Source Community in Africa&lt;/a&gt;, attending the &lt;a href="https://festival.oscafrica.org/" rel="noopener noreferrer"&gt;Open Source Festival&lt;/a&gt; and so much more. Trust me, the things you will learn in a short time would amaze you.&lt;/p&gt;

&lt;p&gt;This article was inspired by my talk at the Hacktoberfest hackathon in Kampala last year and my colleague &lt;strong&gt;Damola Adekoya&lt;/strong&gt; who told me it would be great to write an article about my open source journey.&lt;/p&gt;

&lt;p&gt;Happy to answer any and all questions regarding Open Source contributions, &lt;a href="https://twitter.com/Didicodes" rel="noopener noreferrer"&gt;feel free to send me a DM me on Twitter&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>education</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
