<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Abhi.dev]]></title><description><![CDATA[Abhi.dev]]></description><link>https://abhi23.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 24 Oct 2026 11:04:09 GMT</lastBuildDate><atom:link href="https://abhi23.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Why GitHub Is Rebuilding Its Git Infrastructure for AI Agents]]></title><description><![CDATA[AI coding agents are pushing GitHub to rethink its Git infrastructure. Learn how GitHub is redesigning it's architecture to support the workflow]]></description><link>https://abhi23.hashnode.dev/why-github-is-rebuilding-its-git-infrastructure-for-ai-agents</link><guid isPermaLink="true">https://abhi23.hashnode.dev/why-github-is-rebuilding-its-git-infrastructure-for-ai-agents</guid><category><![CDATA[AI]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[Git]]></category><category><![CDATA[software development]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Software Engineering]]></category><dc:creator><![CDATA[Abhijit Ghosh]]></dc:creator><pubDate>Fri, 23 Oct 2026 02:52:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/d1845928-73f8-49c0-bb73-d6e13d43d3bd.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>AI coding agents have changed how fast you can write code. But what happens when the infrastructure underneath can’t keep up with that pace?</p>
<p>GitHub recently shared numbers that show how big this shift is. In September 2026 alone, developers and agents made 7.38 billion commits on GitHub. That is more than five times the number from a year earlier.</p>
<p>Between September 2025 and August 2026, it more than doubled, from 218.2 billion events per month to 473.3 billion.</p>
<p>GitHub says agentic development is driving this growth, and it is now rebuilding the Git infrastructure behind the platform to handle it. In this article, you’ll learn what is changing, why the old design struggles with agents, and how GitHub plans to fix it, in simple terms.</p>
<p>(Source: <a href="https://github.blog/engineering/architecture-optimization/building-git-infrastructure-for-agent-scale-development/">GitHub Engineering Blog</a>)</p>
<h2>Table of Contents</h2>
<ul>
<li><a href="#heading-why-ai-coding-agents-are-changing-software-development">Why AI Coding Agents Are Changing Software Development</a><ul>
<li><a href="#heading-how-ai-agents-change-the-development-workflow">How AI Agents Change the Development Workflow</a></li>
<li><a href="#heading-how-one-push-triggers-more-work">How One Push Triggers More Work</a></li>
</ul>
</li>
<li><a href="#heading-why-githubs-existing-architecture-struggles-to-scale">Why GitHub's Existing Architecture Struggles to Scale</a><ul>
<li><a href="#heading-how-github-stores-git-repositories">How GitHub Stores Git Repositories</a></li>
<li><a href="#heading-the-architectural-bottleneck-why-scaling-reads-makes-writes-harder">The Architectural Bottleneck: Why Scaling Reads Makes Writes Harder</a></li>
<li><a href="#heading-where-the-old-architecture-hits-a-ceiling">Where the Old Architecture Hits Its Ceiling</a></li>
<li><a href="#heading-what-happens-when-a-fileserver-fails">What Happens When a Fileserver Fails?</a></li>
</ul>
</li>
<li><a href="#heading-how-github-is-redesigning-its-git-infrastructure">How GitHub Is Redesigning Its Git Infrastructure</a><ul>
<li><a href="#heading-separate-storage-from-compute">Separate Storage From Compute</a></li>
<li><a href="#heading-how-github-plans-to-make-pushes-faster">How GitHub Plans to Make Pushes Faster</a></li>
<li><a href="#heading-how-github-moves-maintenance-off-the-serving-path">How GitHub Moves Maintenance Off the Serving Path</a></li>
</ul>
</li>
<li><a href="#heading-adapt-or-get-left-behind">Adapt or Get Left Behind</a></li>
</ul>
<hr />
<h1>Why AI Coding Agents Are Changing Software Development</h1>
<h2>How AI Agents Change the Development Workflow</h2>
<p>Humans and AI coding agents do not use Git in the same way. A developer might push a few times a day. If a push takes a second or two, you will not even notice it.</p>
<p>An agent works differently. It saves its progress after almost every small step, so it commits and pushes again and again. Each time, it has to wait for the push to finish before moving ahead.</p>
<p>Imagine waiting two seconds after typing every sentence in a document. You would feel it very quickly. This is what an agent faces. The time a push takes becomes the speed limit for the whole workflow.</p>
<h2>How One Push Triggers More Work</h2>
<p>The problem does not end after the push. Many automated systems react to every new commit. For example:</p>
<ul>
<li>A continuous integration (CI) pipeline clones the repository to run tests.</li>
<li>Security scanners clone it to check for vulnerabilities.</li>
<li>Other agents fetch the new changes to continue their own work.</li>
</ul>
<p>Cloning means downloading the full repository, and fetching means downloading only the latest changes.</p>
<p>GitHub says CI and code scanning alone can clone or fetch the same branch thousands of times per minute. This pattern, where one action spreads into many, is called fan-out. GitHub Actions ran 3.26 billion times in September 2026, which is more than four times the number from a year earlier.</p>
<p>So every push (a write) creates a large number of reads. These reads must stay fast and cheap, otherwise everything slows down.This is where the old design starts to struggle</p>
<hr />
<h1>Why GitHub's Existing Architecture Struggles to Scale</h1>
<p>To understand why the old architecture struggles, let's look at how GitHub stores repositories and why that design becomes a bottleneck for agentic workflows.</p>
<h2>How GitHub Stores Git Repositories</h2>
<p>GitHub uses a system called Spokes to store and manage Git repositories across multiple fileservers. It keeps copies of each repository in sync so GitHub can handle operations like cloning, fetching, and pushing code.</p>
<p>When a repository is created on GitHub, Spokes assigns it to a set of fileservers - five by default. Each fileserver stores a complete copy of the repository on its local disk. Spokes coordinates these copies to keep the repository data consistent across the fileservers.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><p>A fileserver is a physical or virtual server in GitHub's data center with fast local disks, that stores repository data on those local disks and serves Git operations such as clones, fetches, and pushes.</p></div>
</div>

<p>When a push arrives, Spokes coordinates the write across the repository's replicas using a <strong>quorum-based protocol</strong>.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><p>A quorum is the minimum number of replicas that must participate successfully for an operation to proceed. In a five-replica setup, a majority is three. However, the exact quorum requirements depend on the protocol and operation being performed.</p></div>
</div>

<h2>The Architectural Bottleneck : Why Scaling Reads Makes Writes Harder</h2>
<p>Now that we understand how GitHub stores repositories, let's look at a problem with this architecture.</p>
<p>Agentic workflows can generate more repository activity than traditional development workflows. CI pipelines, security scanners, and other agents may repeatedly clone or fetch the same repository. As this read traffic grows, GitHub needs a way to serve more requests without slowing down the systems that accept new changes.</p>
<p>In the existing architecture, one way to increase read capacity is to add more fileservers and replicate repository data across them. More replicas can help distribute read traffic, but they also introduce a trade-off.</p>
<p>Remember how Spokes coordinates writes across repository replicas using a quorum-based protocol ?</p>
<p>When a developer or an AI agent pushes new changes, Spokes has to coordinate the write across the fileservers.</p>
<p>When a push updates a reference, Spokes uses a three-phase commit protocol and a quorum to keep repository state consistent. Because the replicas participate in the write, the push can be limited by the slowest replica. Adding replicas to handle more reads can therefore increase the cost of writes.</p>
<p>Now, if GitHub adds more fileservers to handle more read requests, it also has more replicas to manage. This can make writes more complicated and increase the time needed to complete them.</p>
<p>In simple terms, adding more fileservers can help handle more reads, but it can also make writes slower.</p>
<p><strong>The infrastructure used to increase read capacity is also involved in the process of accepting writes.</strong> Optimizing one side of the workload can therefore make the other side more expensive.</p>
<p>This becomes a bigger problem when AI agents push changes frequently while CI pipelines and other systems keep reading the repository.</p>
<p>So, the question is: Can GitHub handle more read requests without making writes slower?</p>
<p>That's exactly what GitHub wants to solve with its new architecture.</p>
<h2>Where the Old Architecture Hits Its Ceiling</h2>
<p>The ceiling comes from a fundamental design choice - durability and scale are the same mechanism. The fileserver replicas are both your serving fleet and backup plans.</p>
<p>This creates three problems:</p>
<ul>
<li>Scaling reads hurts writes.</li>
<li>Scaling writes hurts reads.</li>
<li>You can't optimise one at a single time without hurting other.</li>
</ul>
<h2>What Happens When a Fileserver Fails?</h2>
<p>Let's say one of the five fileserver holding your repository dies. Whether it's disk crashes , the machine lose power or for any other reason.</p>
<p>Now you lose two things :</p>
<ul>
<li>You lose one read server - only four machines can serve clone and fetch requests for that repo. Read capacity dropped by 20%</li>
<li>You lose one durable copy - only four copies of your repo exists instead of five. Your safety margin shrank.</li>
</ul>
<hr />
<h1>How GitHub Is Redesigning Its Git Infrastructure</h1>
<p>Now, let's see how GitHub plans to handle the growing demands of agentic workflows.</p>
<h2>Separate Storage From Compute</h2>
<p>One of the major changes is separating the storage layer from the compute layer.</p>
<p>In the new architecture repository data will be stored in Azure Blob Storage, which handles data durability and replication. Lightweight compute workers will handle incoming Git requests. The workers will cache data locally to serve requests faster and fetch it from Azure Blob Storage when needed.</p>
<p>Now, when GitHub needs to handle more read traffic, it can simply add more compute workers without adding more replicas to the write path. This means it can increase read capacity without adding the same overhead to writes.</p>
<p>And if a compute worker fails, the repository data is still safe because the actual data lives in Azure Blob Storage. Another worker can take over the requests.</p>
<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><p><strong>Compute Worker</strong> is a server that is optimised for processing power and speed, not for long-term storage. It has some local disk space which it uses as a cache, but it's primary job is computation : receiving your Git request, processing it, and sending back a response.</p></div>
</div>

<h2>How GitHub Plans to Make Pushes Faster</h2>
<p>In the old system, a push involved several operations before GitHub could confirm that it was complete. These included storing Git objects, checking whether they were connected correctly, running secret scanning, and updating the reference.</p>
<p>Not all these operations need to wait for each other. GitHub's new approach is to reduce the work that must finish before a push can be acknowledged.</p>
<p>The key step is updating the reference, which tells Git where the latest commit is. This update needs coordination to keep the repository consistent. Other work, such as storing objects, checking their connectivity, and scanning for secrets, can happen in parallel with other writes.</p>
<p>By reducing the work that has to wait for coordination, GitHub aims to make pushes faster. For AI agents that commit frequently, even a small reduction in push latency can help them move through their workflows faster.</p>
<h2>How GitHub Moves Maintenance Off the Serving Path</h2>
<p>Previously, repository maintenance tasks, such as compaction and garbage collection, ran on the same fileservers that handled live Git requests. This meant background tasks could compete with incoming requests for CPU, memory, and other resources.</p>
<p>To solve this, GitHub plans to introduce separate workers to handle repository maintenance directly on data stored in Azure Blob Storage. This keeps maintenance work separate from the workers handling live Git requests.</p>
<p>Now, live Git requests and background maintenance run separately, so cleanup tasks are less likely to compete with live requests for the same resources. This helps keep repository operations responsive even as the workload grows.</p>
<hr />
<h2>Adapt or Get Left Behind</h2>
<p>AI coding agents are evolving faster than ever. They're changing how we write code, build software, and think about development itself. Tasks that once took hours can now be completed in minutes.</p>
<p>But the bigger lesson isn't just about writing code faster. It's about how the entire software development ecosystem needs to evolve alongside these tools.</p>
<p>GitHub's infrastructure redesign is a great example. As developers change how they work, the systems supporting them must change, too.</p>
<p>Either you evolve with time, or time leaves you behind.</p>
<p>Happy Coding :)</p>
]]></content:encoded></item><item><title><![CDATA[Routing in Angular]]></title><description><![CDATA[Hi, I'm Abhi. I write articles - real ones, not AI slop. Human written, human friendly & for humans. So I'm a full-stack dev ( MERN / PERN ). React…]]></description><link>https://abhi23.hashnode.dev/routing-in-angular</link><guid isPermaLink="true">https://abhi23.hashnode.dev/routing-in-angular</guid><dc:creator><![CDATA[Abhijit Ghosh]]></dc:creator><pubDate>Thu, 30 Jul 2026 17:41:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/07e39465-1b00-43cf-b46a-6b4e18349171.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi, I'm Abhi. I write articles - real ones, not AI slop. Human written, human friendly &amp; for humans.</p>
<p>So I'm a full-stack dev ( MERN / PERN ). React, Express, Node, that's my comfort zone. But recently I started learning Angular, and routing in Angular is a whole different game. Some things are surprisingly nice, some things made me go "why is this so complicated?"</p>
<p>So instead of just learning and forgetting, I thought why not write about it? If you're also a React dev exploring Angular for the first time, this one's for you.</p>
<p>Stay tuned and have a look at the sections below.</p>
<h1>What’s in this Article !</h1>
<ul>
<li><p>How Routing Works in Angular (the mental model, <code>RouterModule</code>, <code>app-routing.module</code>)</p>
</li>
<li><p>Basic Routing Example</p>
</li>
<li><p>Lazy Loading (brief intro)</p>
</li>
</ul>
<p>Before starting, I would like to mention - I am not an expert in Angular. I just started exploring it and I'm sharing my knowledge here. So you get to see a React guy's POV while learning Angular sideways.</p>
<h1>How Routing works in Angular.</h1>
<p>So unlike React - where we have to install npm packages and use React Router or TanStack Router for routing, because React doesn't have routing on its own - in Angular it's totally different. It provides a prebuilt routing architecture that we can use while building projects, and this is what they use in production grade products too.</p>
<p>This is called the <strong>Angular Router</strong> ( @angular/router ). It comes built-in when you create a project using the Angular CLI.</p>
<p>We don’t have to do npm install, or any third party package, nothing. Just create a project and start routing.</p>
<p>So how to use this? Since i’m using Angular 22 , so we are going to stick to this, we'll be using the standalone approach. If you see older tutorials using RouterModule.forRoot() and app-routing.module.ts , that's the old way. We are not doing that here.</p>
<p>Now before jumping into code, let me quickly explain the key pieces you need to know:</p>
<h2>Routes</h2>
<p>This is just an array where you define which path should load which component. If you've used React Router, think of it like your route config array. Something like <code>{ path: 'about', component: AboutComponent }</code>.</p>
<h2>ProvideRouter()</h2>
<p>This is how you register your routes in <code>app.config.ts</code>. You pass your routes array inside this function and Angular takes care of the rest.</p>
<p>This is the placeholder in your HTML where the matched component will render. If you know React Router, this is basically <code>&lt;Outlet /&gt;</code>. You put this in your <code>app.component.html</code> and Angular will swap components in and out of this spot based on the URL.</p>
<h2>routerLink</h2>
<p>This is Angular's version of <code>&lt;Link to="/" /&gt;</code> from React Router. Instead of using <code>&lt;a href=""&gt;</code> (which will reload the whole page), you use <code>routerLink</code> for client-side navigation. Looks like this: <code>&lt;a routerLink="/about"&gt;About&lt;/a&gt;</code>.</p>
<p>That's it. These four things are all you need to set up basic routing in Angular. If you already know React Router, here's a quick cheat sheet:</p>
<hr />
<h1>Basic Routing Example</h1>
<p>So , now it’s time to build something. Now we are going to build an Angular app with 4/5 pages.</p>
<p>Follow the steps below:</p>
<h2>Step - 1 :</h2>
<p>Create a new Angular app.</p>
<pre><code class="language-shell">ng new angular-routing
</code></pre>
<p>It will ask you few questions, mae sure to click yes while setting up a new app.</p>
<h2>Step - 2 :</h2>
<p>Generate the Components</p>
<pre><code class="language-shell">ng g c about
ng g c contact
ng g c home
ng g c pricing
</code></pre>
<p>After this your folder structure should look somethig like this-</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/1913eff5-e544-4ddc-8385-3b75c14f9651.png" alt="" style="display:block;margin:0 auto" />

<p>You can add some basic text in those components tempalte files. So that you can identify the pages easily.</p>
<h2>Step - 3 :</h2>
<p>Now it’s time to define the routes.</p>
<p>In the app folder, you can see a file named as - app.route.ts</p>
<p>Open this file and initially it shold look like this -</p>
<pre><code class="language-typescript">import { Routes } from '@angular/router';

export const routes: Routes = [];
</code></pre>
<p>now we are going to write the routing of our project here .</p>
<p>For this- you need to import all components and add them inside the array. this should look like this -</p>
<pre><code class="language-typescript">import { Routes } from '@angular/router';
import { About } from './about/about';
import { Contact } from './contact/contact';
import { Home } from './home/home';
import { Pricing } from './pricing/pricing';

export const routes: Routes = [
    {path:'', component: Home},
    {path:'about', component: About},
    {path:'contact', component: Contact},
    {path:'pricing', component: Pricing},
     { path: '**', component: NotFound }
];
</code></pre>
<p>If you've used React Router, this is basically your route config array.</p>
<p>That ** refers to wildcard routes, you can obviously create a not-found page and assign it there .</p>
<h2>Step - 4 :</h2>
<p>Now it’s tme to register the routes.</p>
<p>Open the app.config.ts file and here we need to register the routes in our app.</p>
<pre><code class="language-typescript">import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
import { provideRouter } from '@angular/router';

import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideBrowserGlobalErrorListeners(),
    provideRouter(routes)
  ]
};
</code></pre>
<p>You might have to do this manually or there are high chances it is already done for you, depends on how you configured your app.</p>
<p>Now your entire app has the context of your routing. Now it’s time to use it.</p>
<h2>Step - 5 :</h2>
<p>Now it’s time to add and navigation links. Open the app.ts file and write this -</p>
<pre><code class="language-typescript">import { Component, signal } from '@angular/core';
import { RouterOutlet, RouterLink } from '@angular/router';

@Component({
  selector: 'app-root',
  imports: [RouterOutlet, RouterLink],
  templateUrl: './app.html',
  styleUrl: './app.css'
})
export class App {
  protected readonly title = signal('angular-routing');
}
</code></pre>
<p>Important thing to notice here is - In React we don’t need to do this, but in Angular, standalone components need to explicitly declare what they use. Took me a while to get used to this.</p>
<p>Now open the app.html file which is the main template file and write this -</p>
<pre><code class="language-typescript">&lt;nav&gt;
  &lt;a routerLink="/"&gt;Home&lt;/a&gt;
  &lt;a routerLink="/about"&gt;About&lt;/a&gt;
  &lt;a routerLink="/contact"&gt;Contact&lt;/a&gt;
&lt;/nav&gt;

&lt;router-outlet&gt;&lt;/router-outlet&gt;
</code></pre>
<p>We are basically creating a navbar here and providing the context for routing here.</p>
<p>If you want you can create separate navbar and use that here. I”m doing this to keep things easy and minimal.</p>
<hr />
<h1>Lazy Loading.</h1>
<p>For a small app, this is no big deal. But imagine you are working on a production grade product and you have 50 pages.</p>
<p>But your user just want to see the Home page, but their browser is downloading all 50 pages. Obviously this is not the optimised way to handle things.</p>
<p>Now this is where Lazy Loading comes to the game. It only loads a page’s code when the user actually navigate to it. Not before it.</p>
<p>In React this is the same concept but the difference is only how we implement this concept.</p>
<p>As we discussed earlier how to define routes -</p>
<pre><code class="language-typescript">import { AboutComponent } from './pages/about/about.component';

{ path: 'about', component: AboutComponent }
</code></pre>
<p>This is where we add lazy loading concept. Now if you want this page to lazily load then you have to do this -</p>
<pre><code class="language-typescript">{
  path: 'about',
  loadComponent: () =&gt; import('./pages/about/about.component')
    .then(m =&gt; m.AboutComponent)
}
</code></pre>
<p>Important thing to remember - you don’t have to import it at the top.</p>
<p>Now about component will only load when someone actually clicks on it or navigates to it.</p>
<hr />
<p>So yeah, that's it for Part 1. We covered how routing works in Angular, set up a basic routing example from scratch, and looked at lazy loading. If you made it this far, you know enough to start building stuff with Angular routing.</p>
<p>In Part 2 we’ll learn about :</p>
<ul>
<li><p>Route Parameters &amp; Query Params</p>
</li>
<li><p>Nested / Child Routes</p>
</li>
<li><p>Route Guards</p>
</li>
</ul>
<p>If you found this helpful, share it with your dev friends who are still stuck in the React bubble. And follow me so you don’t miss part 2 .</p>
<p>Happy Coding🌻</p>
]]></content:encoded></item><item><title><![CDATA[NVM Explained: Why You Need It and How to Set It Up.
]]></title><description><![CDATA[It's a small program that sits on your machine and manages multiple Node installations. That's its only job — install Node versions and switch between…]]></description><link>https://abhi23.hashnode.dev/nvm-explained-why-you-need-it-and-how-to-set-it-up</link><guid isPermaLink="true">https://abhi23.hashnode.dev/nvm-explained-why-you-need-it-and-how-to-set-it-up</guid><dc:creator><![CDATA[Abhijit Ghosh]]></dc:creator><pubDate>Sun, 12 Jul 2026 19:11:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/471e86d0-d8d5-4a5e-a110-dd95e4fea30d.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>NVM stands for Node Version Manager</h3>
<p>It's a small program that sits on your machine and manages multiple Node installations. That's its only job — install Node versions and switch between them.</p>
<h2>Life Without NVM</h2>
<p>Let's assume we don't know what NVM is, and we install Node on our system. Let's say you installed Node 20 on your system, and it gets installed fine.</p>
<p>Now every project, every command, will use Node 20 — because that's the only version available on your system.</p>
<p>But let's add a twist.</p>
<p>You also install a slightly older version, or another newer version, of Node. Now your system has two versions of Node — one you installed first, and one you installed recently.</p>
<p>So the question is — what happens now? By default, which one gets used in your projects or terminal sessions?</p>
<p>Now things get messy. Your system doesn't have a smart manager like NVM, so there are two possibilities.</p>
<h3>Option A</h3>
<p>The latest install overrides the old one. It doesn't matter whether you installed the latest version first and then an older one, or the other way around — whichever you installed most recently overrides the one before it. That old version is basically gone from your system now.</p>
<h3>Option B</h3>
<p>They conflict and break each other. Now your terminal is confused about which one to use, and starts throwing weird errors.</p>
<h2>Understanding the Real Problem</h2>
<p>When you install Node on your system, it gets installed in a specific path — let's say:</p>
<p><code>/usr/bin/node → Node 20</code></p>
<p>That's one location, and it works fine. Whenever you use the <code>node</code> command, under the hood it points to this path:</p>
<p><code>node command → /usr/bin/node → Node 20</code> ✅</p>
<p>Everything's good — until you install another Node version. Now you have multiple paths on your system where Node lives. So when you type <code>node</code>, it's confused about where to look. Or in the other case, it just picks the first one it finds — and you can't really control that.</p>
<p>This is exactly the problem NVM solves.</p>
<h2>How NVM Solves This Problem</h2>
<p>Instead of installing Node into your system folders, NVM uses its own isolated folders to install different versions of Node. Inside NVM's isolated folders, the different versions never touch each other — no conflicts, nothing.</p>
<p>NVM entirely controls the PATH. When you run <code>nvm use 16</code>, it points your PATH to the folder that has Node 16 installed — and vice versa.</p>
<p>That's the whole solution: isolated folders, and PATH control.</p>
<h2>Setting Up NVM on Linux</h2>
<p><strong>Step 1 — Install NVM</strong></p>
<pre><code class="language-bash">curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
</code></pre>
<p><strong>Step 2 — Reload the terminal</strong></p>
<pre><code class="language-bash">source ~/.bashrc
</code></pre>
<p><strong>Step 3 — Verify the version</strong></p>
<pre><code class="language-bash">nvm --version
</code></pre>
<p><strong>Step 4 — Install the Node versions you want</strong></p>
<pre><code class="language-bash">nvm install 16.20.2
nvm install 20
</code></pre>
<p><strong>Step 5 — Set the default Node version for your machine</strong></p>
<pre><code class="language-bash">nvm alias default 16.20.2
</code></pre>
<h2>Summary</h2>
<p>NVM solves the conflict problem by keeping every Node version in its own isolated folder, and letting you control which one your terminal uses by updating the PATH. Linux uses the original NVM, installed via curl. Windows uses nvm-windows, installed via an exe file. The commands are almost identical on both.</p>
]]></content:encoded></item><item><title><![CDATA[The Beginner’s Guide to Playwright 🎭]]></title><description><![CDATA[Hi, i'm Abhijeet - a full-stack software developer who loves building things and learning new tech along the way. A few days back, I came across an…]]></description><link>https://abhi23.hashnode.dev/the-beginner-s-guide-to-playwright</link><guid isPermaLink="true">https://abhi23.hashnode.dev/the-beginner-s-guide-to-playwright</guid><dc:creator><![CDATA[Abhijit Ghosh]]></dc:creator><pubDate>Wed, 13 May 2026 11:58:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/c6a98e85-c632-422b-bdaf-3d45fe7c300b.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi, i'm Abhijeet - a full-stack software developer who loves building things and learning new tech along the way.</p>
<p>A few days back, I came across an opportunity that I genuinely didn’t want to miss just because I didn’t know Playwright. The problem? I had never really worked with it before, and honestly, it sounded a bit scary at first 😅</p>
<p>So I made a simple decision:<br /><em>Spend 10 hours learning Playwright with zero excuses.</em></p>
<p>Surprisingly, it took me around <em>6 hours</em> to understand the fundamentals, workflow, and how things actually work behind the scenes.</p>
<p>And trust me, those 6 hours were messy 👾<br />I jumped between the official docs, YouTube tutorials, random errors, and yes… asked ChatGPT some very dumb questions too.</p>
<p>So in this blog, I’m going to share everything I learned in those 6 hours — in a simple 6-minute read for you 🚀</p>
<p>By the end of this blog, you’ll be able to:</p>
<ul>
<li><p>Set up Playwright</p>
</li>
<li><p>Run your first test</p>
</li>
<li><p>Record test scripts</p>
</li>
<li><p>Understand locators and assertions</p>
</li>
<li><p>Debug tests properly</p>
</li>
<li><p>Build a small real-world testing workflow</p>
</li>
</ul>
<p>So let’s get started 👨‍💻</p>
<h1></h1>
<p>What is Playwright.</p>
<p>Before understanding what Playwright actually is, just think about how you normally interact with a website.</p>
<p>Let’s say you want to buy something from Amazon. What do you usually do?</p>
<p>Login → search for the item → click the product → add to cart → place the order → make payment → checkout.</p>
<p>That entire process is called a <strong>user flow</strong>.</p>
<blockquote>
<p>With Playwright, we can automate this entire user flow and test whether the app is working correctly or breaking somewhere after new updates.</p>
</blockquote>
<p>Now imagine manually testing this same flow again and again after every small update in the app 💀 Sounds painful, right?</p>
<p>This is exactly where Playwright comes in.👾</p>
<blockquote>
<p>Playwright is an <strong>end-to-end testing and browser automation framework</strong> built by Microsoft that helps developers automate real user interactions inside the browser.</p>
</blockquote>
<p>In simple words, Playwright can automatically do the same things a real user would do:</p>
<ul>
<li><p>click buttons</p>
</li>
<li><p>fill forms</p>
</li>
<li><p>search items</p>
</li>
<li><p>navigate pages</p>
</li>
<li><p>verify results</p>
</li>
<li><p>and test complete workflows automatically</p>
</li>
</ul>
<p>And the best part? It works across multiple browsers like Chrome, Firefox, and Safari using a single framework.</p>
<hr />
<h1>Installation &amp; SetUp</h1>
<p>Installing Playwright is honestly super easy. You just need a Node.js environment and a few commands.</p>
<p>First, create a new project folder and open it inside VS Code.</p>
<p>Then initialize your project:</p>
<pre><code class="language-javascript">npm init -y
</code></pre>
<p>Now install Playwright:</p>
<pre><code class="language-javascript">npm init playwright@latest
</code></pre>
<p>Once you run this command, Playwright will start asking you a few setup questions like:</p>
<ul>
<li><p>Which language do you want to use? (JavaScript / TypeScript)</p>
</li>
<li><p>Where should test files be stored?</p>
</li>
<li><p>Do you want GitHub Actions setup?</p>
</li>
<li><p>Do you want to install Playwright browsers?</p>
</li>
</ul>
<p>After setup, Playwright automatically creates a proper folder structure for you 🪄</p>
<p>You’ll notice files like:</p>
<pre><code class="language-shell">tests/
playwright.config.js
package.json
</code></pre>
<p>It also installs browser binaries for:</p>
<ul>
<li><p>Chrome/Chromium 🌐</p>
</li>
<li><p>Firefox 🦊</p>
</li>
<li><p>WebKit (Safari engine) 🧭</p>
</li>
</ul>
<p>With one setup, you can test across multiple browsers automatically 🚀</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/c3907bb1-c5a7-44a0-ba8c-5b93ecda7dc5.png" alt="" style="display:block;margin:0 auto" />

<hr />
<p>Try to read and understand the <code>playwright.config.js</code> file carefully 👀</p>
<p>That file is basically the <strong>heart of your Playwright setup</strong>.</p>
<p>From there, you can control things like:</p>
<ul>
<li><p>which browser to run tests on 🌐</p>
</li>
<li><p>headless or UI mode 👨‍💻</p>
</li>
<li><p>test timeout ⏱️</p>
</li>
<li><p>screenshots &amp; videos 📸</p>
</li>
<li><p>base URL</p>
</li>
<li><p>parallel testing</p>
</li>
<li><p>retries and much more</p>
</li>
</ul>
<p>At first it may look confusing, but trust me, understanding this one file will make Playwright way easier later on 🚀</p>
<hr />
<h1>Your First Test</h1>
<p>When you install Playwright, it automatically gives you an example test file so you can understand how things actually work.</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/16915fbf-c1cc-4319-b994-c7a8c3196c9d.png" alt="" style="display:block;margin:0 auto" />

<p>At first, this code may look scary 😵‍💫<br />But trust me, it’s much simpler than it looks.</p>
<p>So let’s decode this example step by step 👇</p>
<h3>Step 1 — Importing Playwright Functions</h3>
<pre><code class="language-typescript">import { test, expect } from '@playwright/test';
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>test()</code> → used to create a test</p>
</li>
<li><p><code>expect()</code> → used to verify whether something is working correctly or not</p>
</li>
</ul>
<p>Think of <code>expect</code> like: In real life how we expect things to be that's how expect works here.</p>
<h3>Step 2 — Creating a Test</h3>
<pre><code class="language-typescript">test('has title', async ({ page }) =&gt; {
</code></pre>
<p>this creates a test named <code>"has title"</code>.</p>
<p>And this <code>page</code> object is super important 👀</p>
<p><code>page</code> basically represents the browser tab.<br />Using it, Playwright can:</p>
<ul>
<li><p>open websites</p>
</li>
<li><p>click buttons</p>
</li>
<li><p>type into inputs</p>
</li>
<li><p>navigate pages</p>
</li>
<li><p>and interact like a real user</p>
</li>
</ul>
<h3>Step 3 — Opening a Website</h3>
<pre><code class="language-typescript">await page.goto('https://playwright.dev/');
</code></pre>
<p>This line simply opens the Playwright website in the browser 🌐</p>
<h3>Step 4 — Assertion (Checking Something)</h3>
<pre><code class="language-typescript">await expect(page).toHaveTitle(/Playwright/);
</code></pre>
<p>This is called an <strong>assertion</strong>.</p>
<p>Here Playwright checks whether the page title contains the word <code>"Playwright"</code> or not.</p>
<p>If yes ✅ → test passes<br />If no ❌ → test fails</p>
<hr />
<h1>Understanding the Workflow</h1>
<p>I know it might feel overweling, seeing a lot of new tings at first , but playwright is comparatively easy, Now install a vs code extension named - playwright test for vs code by microsoft.  </p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/0af9edfd-d866-4b38-9f76-204d64df99ac.png" alt="" style="display:block;margin:0 auto" />

<p>Before jumping into recording tests and writing automation scripts, let's understand the actual Playwright workflow.</p>
<p>One thing I really liked about Playwright is that it gives you <em><strong>multiple ways</strong></em> to work with it 👀</p>
<p>You can either:</p>
<ul>
<li><p>use the VS Code extension/tools 🧩</p>
</li>
<li><p>or do everything directly from the command line 💻</p>
</li>
</ul>
<p>I personally started with the VS Code Playwright extension because it makes things way easier for beginners. You get:</p>
<ul>
<li><p>test explorer</p>
</li>
<li><p>run buttons</p>
</li>
<li><p>browser controls</p>
</li>
<li><p>debugging tools</p>
</li>
<li><p>trace viewer</p>
</li>
<li><p>and many other powerful features directly inside VS Code 🚀</p>
</li>
</ul>
<p>But the cool part is — behind the scenes, all of these tools are basically running Playwright commands for you.</p>
<p>For example:</p>
<ul>
<li><p>running tests</p>
</li>
<li><p>debugging</p>
</li>
<li><p>opening UI mode</p>
</li>
<li><p>generating tests</p>
</li>
</ul>
<p>Everything can also be done manually through the terminal.</p>
<p>So while the VS Code tools make the experience smoother, understanding the command-line workflow is equally important because that’s how Playwright is usually used in real projects and CI/CD pipelines.</p>
<hr />
<h1>Recording Tests 🌀</h1>
<p>This was honestly one of the coolest parts of Playwright for me 😄</p>
<p>Instead of manually writing every single line of automation code, Playwright can actually watch your actions inside the browser and generate the test code automatically.</p>
<p>Yes… literally 😵‍💫</p>
<blockquote>
<p>You open a browser, click buttons, type into inputs, navigate pages - and Playwright keeps generating the code in real time.</p>
</blockquote>
<p>This feature is called <strong>Codegen</strong>.</p>
<p>You can start it using the command line:</p>
<pre><code class="language-bash">npx playwright codegen
</code></pre>
<p>Or directly from the VS Code Playwright tools 🧩</p>
<p>Once it starts, a browser window opens and starts recording your actions.</p>
<p>For example:</p>
<ul>
<li><p>login to a website</p>
</li>
<li><p>search for a product</p>
</li>
<li><p>click buttons</p>
</li>
<li><p>fill forms</p>
</li>
<li><p>submit data</p>
</li>
</ul>
<p>And Playwright converts all those actions into actual automation scripts automatically 🚀</p>
<p>Something like this:</p>
<pre><code class="language-js">await page.goto('https://example.com');
await page.getByRole('textbox').fill('Abhi');
await page.getByRole('button', { name: 'Login' }).click();
</code></pre>
<p>This helped me understand the workflow way faster because instead of thinking:</p>
<blockquote>
<p>“What code should I write?”</p>
</blockquote>
<p>I could first perform the action manually and then observe how Playwright writes the code behind the scenes 👀</p>
<p>One more cool thing I noticed: Playwright also tries to generate smart locators automatically instead of giving random messy selectors all the time.</p>
<p>And honestly, Codegen is one of the fastest ways for beginners to start learning Playwright without feeling overwhelmed.</p>
<p>These are the tolls that will help you to pick locator, assert visibility, assert text, assert value.</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/bc21000c-557d-4ed7-831a-7e062779955f.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h1>Understanding Locators 📍</h1>
<p>Now here comes one of the most important concepts in Playwright - <strong>Locators</strong>.</p>
<p>In simple words, locators help Playwright find elements on the page.</p>
<p>Because think about it 🤔 If Playwright wants to click a button or type inside an input field, it first needs to know:</p>
<blockquote>
<p>“Which exact element should I interact with?”</p>
</blockquote>
<p>That’s where locators come in.</p>
<p>For example:</p>
<pre><code class="language-js">await page.getByRole('button', { name: 'Login' }).click();
</code></pre>
<p>Here Playwright finds the <strong>Login button</strong> and clicks it.</p>
<hr />
<h2>Common Locators You’ll Use 👇</h2>
<h3>By Role</h3>
<pre><code class="language-js">page.getByRole('button', { name: 'Submit' })
</code></pre>
<p>This is one of the best and most reliable ways because it works similar to how real users and screen readers interact with the page.</p>
<hr />
<h3>By Text</h3>
<pre><code class="language-js">page.getByText('Welcome')
</code></pre>
<p>Finds elements using visible text.</p>
<hr />
<h3>By Label</h3>
<pre><code class="language-js">page.getByLabel('Email')
</code></pre>
<p>Super useful for forms and input fields.</p>
<hr />
<h3>By Placeholder</h3>
<pre><code class="language-js">page.getByPlaceholder('Enter password')
</code></pre>
<p>Targets input placeholders directly.</p>
<hr />
<h3>By Test ID</h3>
<pre><code class="language-js">page.getByTestId('login-btn')
</code></pre>
<p>Very commonly used in real-world projects because it stays stable even if UI changes.</p>
<hr />
<h2>Why Locators Matter So Much ⚡</h2>
<p>Bad locators = flaky tests 💀</p>
<p>If your locator is weak or unstable, your tests may randomly fail after small UI updates.</p>
<p>That’s why Playwright recommends using:</p>
<ul>
<li><p>roles</p>
</li>
<li><p>labels</p>
</li>
<li><p>text</p>
</li>
<li><p>test ids</p>
</li>
</ul>
<p>instead of complicated CSS selectors whenever possible.</p>
<p>And honestly, once you understand locators properly, writing Playwright tests becomes way easier 🚀</p>
<hr />
<h2>Assertions ✨</h2>
<p>So far we learned how to:</p>
<ul>
<li><p>open a website</p>
</li>
<li><p>click buttons</p>
</li>
<li><p>fill forms</p>
</li>
<li><p>interact with elements</p>
</li>
</ul>
<p>But here’s the real question 👀</p>
<p>How do we actually verify that things are working correctly?</p>
<p>That’s where <strong>Assertions</strong> come in.</p>
<p>Assertions are basically checks that confirm whether the expected result happened or not.</p>
<p>For example:</p>
<ul>
<li><p>Did the login succeed?</p>
</li>
<li><p>Is the heading visible?</p>
</li>
<li><p>Did the page redirect correctly?</p>
</li>
<li><p>Is the error message showing?</p>
</li>
<li><p>Did the cart update?</p>
</li>
</ul>
<p>Without assertions, Playwright would just perform actions blindly without verifying anything.</p>
<hr />
<h2>Example of an Assertion 👇</h2>
<pre><code class="language-javascript">await expect(page).toHaveTitle(/Playwright/);
</code></pre>
<p>Here Playwright checks whether the page title contains <code>"Playwright"</code> or not.</p>
<p>If yes ✅ → test passes If no ❌ → test fails</p>
<hr />
<h2>Some Common Assertions</h2>
<h3>Check Visibility</h3>
<pre><code class="language-js">await expect(page.getByText('Welcome')).toBeVisible();
</code></pre>
<p>Checks whether an element is visible on the page.</p>
<hr />
<h3>Check Text</h3>
<pre><code class="language-js">await expect(page.getByRole('heading')).toHaveText('Dashboard');
</code></pre>
<p>Verifies exact text content.</p>
<hr />
<h3>Check URL</h3>
<pre><code class="language-js">await expect(page).toHaveURL('https://example.com/dashboard');
</code></pre>
<p>Checks whether the current URL is correct.</p>
<hr />
<h3>Check Input Value</h3>
<pre><code class="language-js">await expect(page.getByLabel('Email')).toHaveValue('abhi@gmail.com');
</code></pre>
<p>Useful for forms and input validation.</p>
<hr />
<h1>Debugging &amp; Interactive Mode 🐞</h1>
<hr />
<p>While working with Playwright , Your tests <em>will</em> fail sometimes.</p>
<p>And honestly, that’s normal.</p>
<p>Sometimes the locator breaks, sometimes the page loads slowly, sometimes the element is not found… and this is exactly where Playwright’s debugging tools become super useful 🚀Interactive UI Mode 👨‍💻</p>
<p>Playwright comes with an amazing Interactive UI Mode that lets you visually run and inspect your tests.</p>
<p>You can start it using:</p>
<pre><code class="language-bash">npx playwright test --ui
</code></pre>
<p>Once it opens, you can:</p>
<ul>
<li><p>run tests visually</p>
</li>
<li><p>see each test step</p>
</li>
<li><p>inspect failures</p>
</li>
<li><p>watch browser actions live</p>
</li>
<li><p>replay tests</p>
</li>
<li><p>debug easily</p>
</li>
</ul>
<p>Honestly, this made learning Playwright way easier for me because I could literally <em>see</em> what was happening instead of guessing blindly 😭</p>
<hr />
<h2>Final Thoughts 🌻</h2>
<p>Honestly, there’s still <em>a lot</em> more to explore in Playwright.</p>
<p>Things like:</p>
<ul>
<li><p>CI/CD integration</p>
</li>
<li><p>advanced debugging</p>
</li>
<li><p>reporting</p>
</li>
<li><p>and scaling large test suites</p>
</li>
</ul>
<p>This blog was just a beginner-friendly guide to help you get started without feeling overwhelmed.</p>
<p>And trust me, Playwright looks scary only in the beginning 😄 Once you understand the workflow, things start making sense pretty quickly.</p>
<p>My biggest advice would be: Don’t try to memorize everything.</p>
<p>Instead:</p>
<ul>
<li><p>run tests</p>
</li>
<li><p>break things</p>
</li>
<li><p>debug errors</p>
</li>
<li><p>experiment with locators</p>
</li>
<li><p>and build small real-world flows</p>
</li>
</ul>
<p>That’s honestly the fastest way to learn.</p>
<p>I learned most of this in around 6 hours just by trying things myself, getting confused, reading docs, watching videos, and asking questions constantly 😂</p>
<p>So if you’re someone who was avoiding Playwright because it sounded complicated… hopefully now it feels a little less scary 👨‍💻</p>
<p>Happy Testing 🌻</p>
]]></content:encoded></item><item><title><![CDATA[Monolith to Microservices: Not as Scary as It Sounds]]></title><description><![CDATA[Everything in One vs Everything Separate.]]></description><link>https://abhi23.hashnode.dev/monolith-to-microservices-not-as-scary-as-it-sounds</link><guid isPermaLink="true">https://abhi23.hashnode.dev/monolith-to-microservices-not-as-scary-as-it-sounds</guid><dc:creator><![CDATA[Abhijit Ghosh]]></dc:creator><pubDate>Tue, 31 Mar 2026 13:31:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/13e096fc-72ed-463c-994e-b2ddd8630f56.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you are someone who has just started in tech, then you must have heard about <em>Monolith</em> and <em>Microservice architecture</em>.</p>
<p>And if you’re reading this, there’s a high chance that you didn’t even bother to Google it or ask ChatGPT.</p>
<p>But don’t worry — I’m no different. I was in the exact same place.</p>
<p>After hearing these terms again and again, I finally decided to Google them and do some basic research. And you know what?</p>
<p>It’s not as complicated as it sounds.</p>
<p><strong>Monolith. Microservice.</strong><br />Big scary words… but very simple ideas.</p>
<p>The names might scare you, but under the hood, these are just design choices — ways to structure your application depending on your requirements and how much you want to scale.</p>
<p>So today, we’re going to break this down in the simplest way possible.</p>
<p>No overcomplicated definitions. No boring theory.</p>
<p>Just clear understanding.</p>
<p>Let’s get started 🚀</p>
<h1>MONOLITH</h1>
<p>If you came this far, I’m assuming you’re a grown man/woman, and you’ve probably gone grocery shopping at least once in your life.</p>
<p>Monolith architecture is like your shopping cart.</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/9d01ade3-34cb-4db0-8bc6-3988efd7aef0.png" alt="" style="display:block;margin:0 auto" />

<p>I’m not talking about your digital cart. Imagine the physical carts kept at the entrance of a supermarket, stacked together in a long line. You pick one, walk through the aisles, and keep throwing everything into that single cart.</p>
<p>Everything. In one place.</p>
<p>That’s exactly how monolith architecture works.</p>
<p>You keep every required service of your application in a single codebase, running as one system.</p>
<p>For example, I recently built <a href="http://tokenmitra.online">tokenmitra.online</a> — a <em><strong>queue management</strong></em> and <em><strong>appointment automation</strong></em> system for <strong>medical clinics</strong> using the MERN stack.</p>
<p>In <a href="http://tokenmitra.online">tokenmitra.online</a> , I used a <strong>monolithic architecture</strong>. Everything lives in one place:</p>
<p>User, Auth, Bookings, Appointments, Messages — all inside a single application.</p>
<p>This approach is great for beginners (like me). It’s simple to build and easy to manage in the early stages.</p>
<p>But as you might have guessed, everything is tightly coupled.</p>
<p>If one part has an issue or needs scaling, you often end up affecting or scaling the entire application.</p>
<p>Monolith architecture is simple to start but painful to scale...</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/46533918-13a7-4ad4-9f39-83e26fc00ee5.png" alt="" style="display:block;margin:0 auto" />

<h2>Problems with Monolith architecture</h2>
<p>So if you’re not a web crawler gathering data, I can assume that by now you’ve already guessed the problems with monolith architecture. But still for better clarity, let's discuss the problms:</p>
<ul>
<li><strong>Everything is tightly coupled</strong></li>
</ul>
<p>In a monolith, all your services live together.</p>
<ul>
<li><strong>Scaling becomes painful</strong></li>
</ul>
<p>Let’s say only your <strong>booking service</strong> is getting heavy traffic. But in a monolith, you can’t scale just that part.</p>
<p>You have to scale the <em>entire application</em>.</p>
<ul>
<li><strong>Codebase becomes messy over time</strong></li>
</ul>
<p>At the beginning, everything feels clean. But as features grows everything becomes messy.</p>
<ul>
<li><strong>Slower development speed</strong></li>
</ul>
<p>If multiple developers are working you can't increase the development speed.</p>
<ul>
<li><strong>Hard to adopt new tech</strong></li>
</ul>
<p>In monolith: everything uses same tech stack.So if you want to use a new database or try a different language , It becomes very hard without affecting the whole system.</p>
<ul>
<li><strong>Deployment is risky</strong></li>
</ul>
<p>Even a small change requires redeploying the whole app.</p>
<hr />
<h1>MICORSERVICE</h1>
<p>So let’s move on to microservices.</p>
<p>After everything we just discussed, I don’t think I need to repeat the question: <em>“Why do we need microservices?”</em></p>
<p>If you can read (and you made it this far), you already have an idea why.</p>
<p>Now let's talk about What is Microservice.</p>
<p>Let’s go a bit deeper into this.</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/242632ae-667b-4c7f-a33f-9102687f0be1.png" alt="" style="display:block;margin:0 auto" />

<p>In microservices architecture, every service is independent.</p>
<p>As shown in the image, services like Auth, Booking, Messages, and User <em><strong>are all separate</strong></em> and <em>communicate</em> with each other through <em><strong>APIs.</strong></em></p>
<blockquote>
<p>Each service runs in its own space and handles a specific responsibility.<br />This makes the system more organized and easier to manage.</p>
</blockquote>
<p>These services are loosely coupled.<br />Which means changes in one service do not directly affect others.</p>
<p>Because of this:</p>
<ul>
<li><p>You can scale only the service that needs more resources (for example, booking service during high traffic)</p>
</li>
<li><p>The codebase remains cleaner and more maintainable</p>
</li>
<li><p>Teams can work on different services independently</p>
</li>
<li><p>You can use different technologies for different services if needed</p>
</li>
</ul>
<p>Microservices give you more flexibility and control over your application as it grows.</p>
<hr />
<h1>TLDR</h1>
<p>At the end of the day, both monolith and microservices are just different ways to structure your application.</p>
<p>Monolith is simple and a great starting point.<br />Microservices bring flexibility and scalability as your application grows.</p>
<p>There is no “one size fits all”.</p>
<p>It always depends on your use case, your team, and how big your system is going to be.</p>
<p>Happy Coding</p>
]]></content:encoded></item><item><title><![CDATA[How I fixed my SSL certificate issue by migrating from GoDaddy DNS to Cloudflare]]></title><description><![CDATA[So after completing the development of tokenmitra.online , i decided to deploy it. But doing this for the first time… I had to deal with a lot of…]]></description><link>https://abhi23.hashnode.dev/how-i-fixed-my-ssl-certificate-issue-by-migrating-from-godaddy-dns-to-cloudflare</link><guid isPermaLink="true">https://abhi23.hashnode.dev/how-i-fixed-my-ssl-certificate-issue-by-migrating-from-godaddy-dns-to-cloudflare</guid><dc:creator><![CDATA[Abhijit Ghosh]]></dc:creator><pubDate>Fri, 27 Mar 2026 12:13:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/453edddc-c2b4-4d16-a249-e61aa47a5438.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>So after completing the development of <a href="http://tokenmitra.online">tokenmitra.online</a> , i decided to deploy it.  </p>
<p>But doing this for the first time… I had to deal with a lot of issues.<br />One of the major ones was <strong>CORS</strong>, which took some time to figure out.  </p>
<p>I was using <strong>JWT + cookie-based auth</strong>, and I had also bought a cheap domain from GoDaddy and started using it.</p>
<p>I added all the required <strong>A records, CNAME, and all that stuff</strong>.</p>
<p>But the real problem was something deeper… something I didn’t even realize at first.  </p>
<p>My frontend (hosted on Render along with the backend) started showing this error:  </p>
<blockquote>
<p>We weren't able to issue a certificate</p>
</blockquote>
<p>And that’s where the real debugging started… 😅</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/8a82c9c0-0f2e-4dac-ada8-473dbe5ad641.png" alt="" style="display:block;margin:0 auto" />

<p>Honestly, I’m not some expert who understands all these concepts deeply.<br />But I kept trying different things… and kept failing 😅  </p>
<p>At first i thought :</p>
<ul>
<li><p>Maybe I messed up A record</p>
</li>
<li><p>Maybe DNS not propagated</p>
</li>
<li><p>Maybe Render is buggy</p>
</li>
</ul>
<p>But after doing some digging, I realized the issue is something else… something I didn’t even understand.</p>
<p>So I did what every developer does 😅<br />I used LLMs to figure out what was actually going wrong.</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/cfb94340-2f03-4397-818b-9e76c4807e47.png" alt="" style="display:block;margin:0 auto" />

<h1>The Actual Problem</h1>
<p>I realised the issue was with GoDaddy DNS, not my code, not my deployment.</p>
<p>GoDaddy silently adds something called CAA records ( Certification Authority Authorization).</p>
<p>These records basically says :</p>
<blockquote>
<p>Only specific companies can issue SSL certifcates for this domain.</p>
</blockquote>
<p>Now the thing is :</p>
<ul>
<li><p>Render uses something known as - Let's Encrypt</p>
</li>
<li><p>GoDaddy's default CAA does not always allow it .</p>
</li>
</ul>
<p>So render tried → Got blocked → SSL failed 🥲</p>
<h1>How i Debugged it</h1>
<p>After showign this error multiple time , the first thought came to my mind was -  </p>
<ul>
<li><p>I'm doing nothing wrong.</p>
</li>
<li><p>Domain pointing correctly .</p>
</li>
<li><p>App working on default domain .</p>
</li>
<li><p>But only SSL failing</p>
</li>
</ul>
<p>Now as someone who has no experience working with all these , i used LLM chatbots to find a solution. And then i get to know that -</p>
<blockquote>
<p>Instead of fighting wiht GoDaddy DNS i can replace it with something better.</p>
</blockquote>
<h1>The Fix: Moving DNS to Cloudflare</h1>
<p>Here is exactly what i did.</p>
<h2>Step 1 : Created a Cloudflare Account</h2>
<p>Go to Cloudflare.</p>
<p>Sign up ( i choose the free plan )</p>
<h2>Step 2 : Add your Domain</h2>
<p>Click "Add a site"</p>
<p>Enter your domain : <a href="http://tokenmitra.online">tokenmitra.online</a></p>
<p>Choose Free plan</p>
<p>Now Cloudflare will automatically Scan your existing DNS &amp; import A, CNAME etc.</p>
<h2>Step 3 : Verify DNS Records</h2>
<p>Double check these things :</p>
<ul>
<li><p>A record → Points to your backend ( mine was pointing to render )</p>
</li>
<li><p>CNAME → Points to frontend ( i deployed my fronted in vercel this time)</p>
</li>
</ul>
<p>Don't blindly trust import - verify everything.</p>
<h2>Step 4 : Change Nameservers in GoDaddy</h2>
<p>Go to GoDaddy</p>
<ul>
<li><p>Open your domain settings</p>
</li>
<li><p>Find Nameservers</p>
</li>
<li><p>Replace :</p>
</li>
</ul>
<blockquote>
<p><a href="http://ns01.domaincontrol.com">ns01.domaincontrol.com</a><br /><a href="http://ns02.domaincontrol.com">ns02.domaincontrol.com</a></p>
</blockquote>
<p>With Cloudflare nameservers (example):</p>
<blockquote>
<p><a href="http://cruz.ns.cloudflare.com">cruz.ns.cloudflare.com</a></p>
<p><a href="http://dean.ns.cloudflare.com">dean.ns.cloudflare.com</a></p>
</blockquote>
<p>This is the main switch - now Cloudflare controls your DNS.</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/3bd352cd-6ab7-41b5-b480-ccd8e8e0b646.png" alt="" style="display:block;margin:0 auto" />

<h2>Step 5 : Wait for DNS Propagation</h2>
<p>Now as you have almost done everything, but one thing to remember, still you have to wait and the time depends from 10-60 minutes.</p>
<p>In my case i just sleep and woke up with everything running.</p>
<p>Now Cloudflare is active &amp; GoDaddy DNS is no longer being used.</p>
<h2>Step 6 : Retry SSL Insurance</h2>
<p>Now go back to Render dashboard &amp; trigger redeploy or Wait.</p>
<p>This time you will find no errors.</p>
<h1>Final Thoughts</h1>
<p>This bug taught me someting important:</p>
<blockquote>
<p>Sometimes the problem is not in your code,</p>
<p>It's in the infrastructure around it .</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Modern Routing in React : A Practical Guide to React Router DOM with createBrowserRouter]]></title><description><![CDATA[If you’ve just started with React and are curious about how routing works in modern React apps, this is the perfect place for you. In this article, I’m…]]></description><link>https://abhi23.hashnode.dev/modern-routing-in-react-a-practical-guide-to-react-router-dom-with-createbrowserrouter</link><guid isPermaLink="true">https://abhi23.hashnode.dev/modern-routing-in-react-a-practical-guide-to-react-router-dom-with-createbrowserrouter</guid><dc:creator><![CDATA[Abhijit Ghosh]]></dc:creator><pubDate>Mon, 23 Mar 2026 12:40:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/958423c2-d807-4b56-8420-4ccec8d77976.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you’ve just started with React and are curious about how routing works in modern React apps, this is the perfect place for you.</p>
<p>In this article, I’m going to explain routing in modern React apps, along with a simple setup guide.</p>
<p>So, let’s get started 🚀</p>
<p>When i started learning about routing in react, at first i get overwelmed .</p>
<p>BrowserRouter, RouterProvider, createBrowserRouter — too many things to digest .</p>
<p>But instead of just watching some random youtube tutorial i tried to understand things, and here i'm going to share what i have understand so far.</p>
<h1>React Router vs React Router DOM</h1>
<p>So, the first confusing thing in this journey is understanding what <strong>React Router</strong> and <strong>React Router DOM</strong> actually are.</p>
<p>If you dig a little deeper, you’ll find that <strong>React Router</strong> is the core package - it contains all the <strong>main routing logic</strong> and <strong>functionalities.</strong></p>
<p>On the other hand, <strong>React Router DOM</strong> is the <strong>web-specific package</strong> used for <em>browser-based React apps.</em> It is built on top of React Router and depends on it, but it’s specifically designed for the web.</p>
<p>So, if you’re working with web apps (which most of us are), you’ll be using <strong>React Router DOM</strong> almost all the time - basically the web version of React Router.</p>
<h1>Installing Dependencies</h1>
<p>To install React Router DOM :</p>
<pre><code class="language-javascript">npm install react-router-dom
</code></pre>
<p>You don't need any extra package, this will do the job for you.</p>
<p>Understanding the Modern Approach</p>
<p>So there are mainly two ways , how you can use routing in react by using react-router-dom.</p>
<blockquote>
<p><strong>Old Way</strong> - BrowserRouter + Routes</p>
<p><strong>Modern Way</strong> - createBrowserRouter + RouterProvider</p>
</blockquote>
<p>Today we are going to learn about the modern approach .</p>
<h2>BrowserRouter + Routes</h2>
<p>This is what everyone learned in 2022–2025. Super simple and readable with JSX.</p>
<ul>
<li><p>Wrap your app with</p>
</li>
<li><p>Define routes using and components</p>
</li>
</ul>
<p>Pros: Easiest to understand, perfect for small/medium apps or beginners.<br />Still 100% supported in v7.</p>
<h2>createBrowserRouter + RouterProvider</h2>
<p>This became the official recommended way starting in v6.4 and is even stronger in v7.</p>
<ul>
<li><p>You define all your routes as a JavaScript array/object</p>
</li>
<li><p>Use createBrowserRouter()</p>
</li>
<li><p>Render everything with</p>
</li>
</ul>
<p>Pros: Unlocks powerful Data APIs (loaders for fetching data before the page renders, actions for forms, parallel loading, built-in error boundaries, pending UI, etc.).</p>
<p>It comes with Better performance and future-proof.</p>
<p>And today we are going to learn about this modern way and do some basic rouer setup using this.</p>
<h1>Setup Guide :</h1>
<h2>Step - 1 : Create Rouer</h2>
<p>Create a <strong>routes</strong> <em>folder</em> <strong>inside your <em>src</em> directory</strong>. Now create a <strong>AppRoutes.jsx</strong> <em>file</em> inside the <em><strong>routes folder.</strong></em></p>
<p>Now this is the perfect place where you can create the router.</p>
<pre><code class="language-javascript">import { createBrowserRouter } from "react-router-dom";
import App from "../App.jsx";
import About from "../pages/publicC/About.jsx";

const router = createBrowserRouter([
  {
    path: "/",
    Component: App,
    children: [
      { index: true, Component: Landing },
      { path: "about", Component: About },
    ],
  },
]);

export default router;
</code></pre>
<p>Now you must be thinking why should i create a separate <strong>routes folder and do all this.</strong></p>
<p>Honestly you don't have to do this , but it's a good practice.</p>
<p>As your app grows, routing can get messy - lots of paths, nested routes, layouts, etc. Keeping everything inside a <strong>routes</strong> folder helps you :</p>
<ul>
<li><p>To keep things organized</p>
</li>
<li><p>Separate routing logic from UI components</p>
</li>
<li><p>Easily find &amp; manage all routes in one place.</p>
</li>
</ul>
<p>Alternatives : You can always do what you want to do, even you can define the routes directly inside <strong>App.jsx</strong> , if your project is small.</p>
<h3><strong>What does "Creating a router" means?</strong></h3>
<p>When we use createBrowserRouter, we basically define all the routes of our app in one place.</p>
<p>You are basically telling react :</p>
<ul>
<li><p>What URL maps to which component</p>
</li>
<li><p>how routes are nested</p>
</li>
<li><p>what should render inside what</p>
</li>
</ul>
<p>This is your app's navigation blueprint</p>
<pre><code class="language-javascript">createBrowserRouter([....])
</code></pre>
<h2>Step - 2 : Add RouterProvider</h2>
<p>Now it's time to add the RouterProvider , so go to your main.jsx file and do this</p>
<pre><code class="language-javascript">import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import { RouterProvider } from "react-router-dom";
import router from "./routes/AppRoutes.jsx";

createRoot(document.getElementById("root")).render(
  &lt;StrictMode&gt;
    &lt;RouterProvider router={router} /&gt;
  &lt;/StrictMode&gt;,
);
</code></pre>
<p>Now let's talk about what does this even mean..<br />So after creating the router, now it's time to connect your router to your app.</p>
<p>Like think about it , you created the routes, but now how your app will know about it ???<br />You have to tell it right .</p>
<p>When you do this :</p>
<pre><code class="language-javascript">&lt;RouterProvider router={router} /&gt;
</code></pre>
<p>You are basically telling React :</p>
<blockquote>
<p>Hey , use this router to control navigation in my app.</p>
</blockquote>
<p>And the router is the router object, that you are exporting from the <strong>AppRoutes.jsx</strong> file.</p>
<p>Without <strong>RouterProvider , your router is just defined ... but not used yet!</strong></p>
<p>Now you must be thinking but why do need to do all these with <strong>main.jsx ??</strong></p>
<p>Because <strong>this is the entry point of your app</strong> - so you wrap your whole app with routing from the start.</p>
<h2>Step - 3 : use Outlet in the App</h2>
<p>Now go to your App.jsx file and do this</p>
<pre><code class="language-javascript">import { Outlet } from "react-router-dom";

const App = () =&gt; {
  return (
    &lt;&gt;
      &lt;Outlet /&gt;
    &lt;/&gt;
  );
};

export default App;
</code></pre>
<p>Ok, so let's try to understand what we just did here .</p>
<p>is basically a placeholder - It tells React Router:</p>
<blockquote>
<p>Render the child route component here only</p>
</blockquote>
<h3>Why do we need Outlet ?</h3>
<p>first look at your roues ;</p>
<pre><code class="language-javascript">{
    path: "/",
    Component: App,
    children: [
      { index: true, Component: Landing },
      { path: "about", Component: About },
    ],
  },
</code></pre>
<p>here :</p>
<ul>
<li><p><strong>App</strong> is the <strong>parent route.</strong></p>
</li>
<li><p><strong>Landing</strong> and <strong>About</strong> are child router.</p>
</li>
</ul>
<p>So when you go to :</p>
<ul>
<li><p>/ - <strong>Landing page</strong> should render</p>
</li>
<li><p>/about - <strong>About page</strong> should render</p>
</li>
</ul>
<p>But where should they render inside App ?</p>
<p>That's where comes in the picture.</p>
<blockquote>
<p>Outlet basically Renders the matching child route in the place of</p>
</blockquote>
<p>Think like this - you have <strong>Navbar</strong> &amp; <strong>Footer</strong> to show in each page, but you don't want to write it everywhere. So now what ?</p>
<p>Now you will use Outlet -</p>
<pre><code class="language-javascript">const App = () =&gt; {
  return (
    &lt;&gt;
      &lt;Navbar /&gt;
      &lt;Outlet /&gt;
      &lt;Footer /&gt;
    &lt;/&gt;
  );
};
</code></pre>
<p>Navbar &amp; Footer stays same , only the middle content changes.</p>
<h1>Nested Routes</h1>
<p>Nested Routes - as you can understand from the name it mean - routes inside routes.</p>
<p>Nesting is useful in real apps, as many pages share the same layout.</p>
<p>For Example :</p>
<ul>
<li><p>Navbar stays same</p>
</li>
<li><p>Footer stays same</p>
</li>
<li><p>Only content changes</p>
</li>
</ul>
<p>So instead of repeating the same code again and again, we use nested routes.</p>
<p>Layouts are just like wrapper components that holds common UI. Like you discussed while talking about .</p>
<pre><code class="language-javascript">{
    path: "/",
    Component: App,
    children: [
      { index: true, Component: Landing },
      { path: "about", Component: About },

      {
        path: "auth",
        Component: AuthLayout,
        children: [
          { path: "login", Component: Login },
          { path: "register", Component: Register },
        ],
      },
    ],
  },
</code></pre>
<p>Here App is the main layout ( Navbar / Footer included within)</p>
<p>AuthLayout is different layout ( no Navbar/ Footer , simple page )</p>
<p>Example :</p>
<ul>
<li><p><code>/</code> → App → Landing</p>
</li>
<li><p><code>/about</code> → App → About</p>
</li>
<li><p><code>/auth/login</code> → AuthLayout → Login</p>
</li>
<li><p><code>/auth/signup</code> → AuthLayout → Signup</p>
</li>
</ul>
<p>Simple Idead : how you can understand -</p>
<ul>
<li><p>Parent = layout</p>
</li>
<li><p>Child = actual page</p>
</li>
<li><p>Outlet = where page shows</p>
</li>
</ul>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/b0a08b3a-480a-4cc3-8432-e0afc7c18338.png" alt="" style="display:block;margin:0 auto" />

<h1>Common Mistakes</h1>
<p>There are some common mistakes that beginners fall easily. So let's talk about those so you can avoid repeating the same mistakes.</p>
<h2>1 - Mixing element &amp; component</h2>
<p>React router has two styles :</p>
<blockquote>
<p>OLD style -</p>
<p>element : <code>&lt;Home/&gt;</code></p>
</blockquote>
<blockquote>
<p>NEW style -</p>
<p>Component : Home</p>
</blockquote>
<p>Don't mix them randomly in the same setup.</p>
<p>Pick one style ( prefer Component for modern apps) and stay consistent.</p>
<h2>2 - Forgetting</h2>
<p>As we discussed about Outlet and it's usecase above, i think you already understand how important it is to use , but still sometimes while working with nested routes you might forget to use it .</p>
<p>And that's what cause problem. Now your child routes will not render at all . So always remember to use Outlet.</p>
<h2>3 - Using BrowserRouter + RouterProvider together</h2>
<p>Using BrowserRouter &amp; RouterProvider is another mistakes that beginners do.</p>
<p>This is wrong and using BrowserRouter is the old way. So try to stay updated with the React Router docs and write code mindfully.</p>
<h2>Common Folder Structure :</h2>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/1a0cc3dd-2d90-48b9-958f-0b1d498df0b8.png" alt="" style="display:block;margin:0 auto" />

<h1>Conclusion</h1>
<p>That’s it for this one.</p>
<p>This blog was just a <strong>beginner-friendly guide</strong> to help you get started with the modern setup using <code>createBrowserRouter</code>. If you can set up routes, use <code>&lt;Outlet /&gt;</code>, and understand nesting - you’re already ahead of many beginners.</p>
<p>Of course, there’s still <strong>more to explore</strong> like data fetching (loaders), error handling, and protected routes. I didn’t cover those here to keep things simple and focused.</p>
<p>You can always refer to the official React Router docs if you want to go deeper - they have everything in detail.</p>
<p>I’ll probably write more about the advanced stuff in the next part.</p>
<p>For now, just try building something small using this setup - that’s where the real understanding comes from 🌻</p>
]]></content:encoded></item><item><title><![CDATA[Promise Methods In Javascript]]></title><description><![CDATA[In this article, we are going to learn about JavaScript Promise methods. Why only methods ? 🤔 Because in this cruel world, everyone can make a promise…]]></description><link>https://abhi23.hashnode.dev/promise-methods-in-javascript</link><guid isPermaLink="true">https://abhi23.hashnode.dev/promise-methods-in-javascript</guid><dc:creator><![CDATA[Abhijit Ghosh]]></dc:creator><pubDate>Tue, 17 Mar 2026 13:22:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/eafedc43-9269-4d1e-ab98-7b67bdb78bdd.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, we are going to learn about <em>JavaScript Promise methods</em>. Why only methods ? 🤔</p>
<p>Because in this cruel world, everyone can make a promise, but no one really knows how to keep a promise. So I'm on a mission to make this world a better place by teaching you not just how to make a promise, but how to actually keep it.😌🤝</p>
<p>So let's get started. But before we jump into Promise methods, I want to explain about- what is a Promise?</p>
<p>Just in case some nerd opens this article who doesn't even know how to make one Promise but is trying to learn the methods. Kind of like me trying to build a full-stack app right after learning HTML.</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/7d28a8a5-e9b0-46e4-8549-3444638b60e3.jpg" alt="" style="display:block;margin:0 auto" />

<h1>What is a JavaScript Promise ?</h1>
<blockquote>
<p>A Promise in JavaScript is an object that represents the eventual completion or failure of an asynchronous task.</p>
</blockquote>
<p>As we all know Javascript is a <em><strong>single-threaded</strong></em> and <em><strong>synchronous</strong></em> language, So it can only handle one task at a time - and that to be a synchronous task.</p>
<p>So now what JavaScript will do when he have to do some async task ?</p>
<blockquote>
<p>Let's take an example from a <em>Bollywood movie</em>.</p>
</blockquote>
<p>You have seen this many times - the hero finds his soulmate and wants to marry her.</p>
<p>But he can't just do it. Why? Because first of all, <strong>this is India</strong>, <em>not</em> <em><strong>Los Angeles</strong></em>.</p>
<p>Our hero needs to convince the <strong>religious + strict + stereotype</strong> father of that girl. And he can only marry her when the father gives the green signal. But trust me my friend this is not easy as it sounds.</p>
<blockquote>
<p>For now, let's say the hero is "RAJ" and the heroine is "SIMRAN"</p>
</blockquote>
<p>And just like our movie, JavaScript works in a similar way. When it needs to handle any async task, it makes a Promise. Now that Promise has 3 states.</p>
<p>Anything can happen. You never know if the strict father will agree or not. In the same way, you never know whether the Promise will resolve or reject.</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/417f0135-d34a-49c8-ab14-e3af79e98cb2.jpg" alt="" style="display:block;margin:0 auto" />

<h1>Three states of a Promise :</h1>
<p><strong>1</strong>- <strong>Pending</strong></p>
<p><em>2-</em> Fulfilled**</p>
<p><em>3-</em> Rejected**</p>
<p>Let's deep dive into what does these states even mean …..</p>
<ul>
<li><p>When promise is pending - RAJ promises to win SIMRAN &amp; He goes to convince her strict father. ( Now RAJ is on his way not reached yet …… still in the train…….) 🏃‍♀️🚂</p>
</li>
<li><p>When promise is fulfilled - RAJ finally convinced SIMRAN'S father's approval. Now RAJ &amp; SIMRAN can live happily ever after:)🧎‍➡️🧍‍♀️</p>
</li>
<li><p>When promise is rejected - RAJ failed to convince SIMRAN'S strict father and SIMRAN married someone else. :( 🧍‍♀️🚂💃</p>
</li>
</ul>
<p>So I hope now you have a better understanding of JavaScript Promises.</p>
<p>And if you are not an Indian, then I assume I just gave you an insider tip on how to make your own Bollywood movie.</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/d7b116ea-53b7-4672-a511-cea9a5d80cac.png" alt="" style="display:block;margin:0 auto" />

<hr />
<p>Now it's time for the main thing. Are you all excited !!!</p>
<p>Let's start discussing about Promise Methods in Javascript.</p>
<h1>Promise Methods in JavaScript</h1>
<p>So in JavaScript Promise we have mainly 2 types of methods -</p>
<h2>Instance Method</h2>
<ul>
<li><p>promise.then()</p>
</li>
<li><p>promise.catch()</p>
</li>
<li><p>promise.finally()</p>
</li>
</ul>
<h2>Static Method</h2>
<ul>
<li><p>Promise.all()</p>
</li>
<li><p>Promise.allSettled()</p>
</li>
<li><p>Promise.race()</p>
</li>
<li><p>Promise.any()</p>
</li>
<li><p>Promise.resolve()</p>
</li>
<li><p>Promise.reject()</p>
</li>
</ul>
<p>Let's start with Instance Methods. But alwys remember one thing before all these one thing has already happened - which is promise creation.</p>
<p>RAJ already promised SIMRAN:</p>
<p>"Simran, I will win your father's approval and come back for you."</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/ca698edb-4657-4fae-a5e7-c0ed95e6227d.jpg" alt="" style="display:block;margin:0 auto" />

<h2>promise.then()</h2>
<p>This method runs when a promise is fulfilled. Which means Happy Ending of our story. Promise is resolved. RAJ finally wins the heart of SIMRAN's strict father.</p>
<blockquote>
<p>.then() executes when :</p>
<ul>
<li><p>Promise is fulfilled</p>
</li>
<li><p>It receives the resolved value.</p>
</li>
</ul>
</blockquote>
<pre><code class="language-javascript">let rajPromise = new Promise((resolve, reject) =&gt; {
    let fatherAgrees = true;

if (fatherAgrees) {
        resolve("Simran mil gayi ❤️");
    } else {
        reject("Bauji ne mana kar diya 💔");
    }
});

rajPromise.then((result) =&gt; {
    console.log("Success:", result);
});
</code></pre>
<p>Now if resolved - .then() runs and we get "Simran mil gayi ❤️ " as result.</p>
<p>If rejected - .then() is skipped.</p>
<p>The interesting thing here is You can always chain .then() and Each .then() returns a new promise. promise</p>
<pre><code class="language-javascript">promise
  .then((res) =&gt; {
    console.log(res);
    return "Cold drink";
  })
  .then((drink) =&gt; {
    console.log(drink);
  });
</code></pre>
<p>Promise chaining is like -</p>
<ul>
<li><p>RAJ wins father</p>
</li>
<li><p>Then marry SIMRAN</p>
</li>
<li><p>Then they live happily …..</p>
</li>
</ul>
<h2>promise.catch()</h2>
<p>This method runs when the promise is rejected.</p>
<p>When SIMRAN'S father says - "Mat ja SIMRAN".</p>
<p>Now the Promise that RAJ made to SIMRAN is rejected. Raj fails &amp; Love story breaks.</p>
<pre><code class="language-javascript">let rajPromise = new Promise((resolve, reject) =&gt; {
    let fatherAgrees = false;

if (fatherAgrees) {
        resolve("Simran mil gayi ❤️");
    } else {
        reject("Bauji ne mana kar diya 💔");
    }
});

rajPromise.then((result) =&gt; {
    console.log("Success:", result);
}).catch((error) =&gt; {
      console.log("Error:", error);
  });
</code></pre>
<p>Now as we can see the fatherAgrees is false , so now the .catch() method will work here and we will get error as - "Bauji ne mana kar diya 💔"</p>
<img src="https://cdn.hashnode.com/uploads/covers/68ba6c188c1bd14b41cdbab6/e808cf7d-58c9-4a93-8b69-5d97af491084.jpg" alt="" style="display:block;margin:0 auto" />

<h2>promise.finally()</h2>
<p>This method runs no matter what happens. It will run whether promise resolved or rejected.</p>
<p>This method is like the TRAIN that leaves anyway.</p>
<p>If RAJ gets SIMRAN or not . The TRAIN will not stop for anyone, it will leave the station.</p>
<pre><code class="language-javascript">rajPromise
  .then((result) =&gt; {
      console.log("Success:", result);
  })
  .catch((error) =&gt; {
      console.log("Error:", error);
  })
  .finally(() =&gt; {
      console.log("Train has left the station 🚂");
  });
</code></pre>
<p>Unlike .then() and .catch() , .finally() doesn't receives any value. It is mainly used for cleanup tasks.</p>
<hr />
<p>Now as we have completed learning about Instance Methods , now let's start our Static Methods.</p>
<h2>Promise.resolve()</h2>
<p>Imagine SIMRAN'S Father immediately says: "Ja SIMRAN, Jee le apni zindagi".</p>
<p>Now there is no struggle.</p>
<p>No delay. Already Successful.</p>
<p>This is exactly how Promise.resolve() works.</p>
<p>It creates a promise that is already fulfilled. let p = Promise.resolve("Simran mil gayi ❤️");</p>
<pre><code class="language-javascript">let p = Promise.resolve("Simran mil gayi ❤️");

p.then(data =&gt; console.log(data)); 
</code></pre>
<blockquote>
<p>Use When:</p>
<ul>
<li><p>You want to return a resolved promise</p>
</li>
<li><p>Convert normal value into promise</p>
</li>
</ul>
</blockquote>
<h2>Promise.reject()</h2>
<p>Now SIMRAN'S Father says : "Bilkul nahi"</p>
<p>Which means her father denied. Now there is No more chance for RAJ to marry SIMRAN. Direct Failure.</p>
<p>And this is how Promise.reject() works. Already rejected promise.</p>
<pre><code class="language-javascript">let p = Promise.reject("Shaadi cancel 💔");

p.catch(err =&gt; console.log(err));
</code></pre>
<blockquote>
<p>You can use this when you want to manually trigger failure.</p>
</blockquote>
<h2>Promise.all()</h2>
<p>Now RAJ must complete All tasks:</p>
<ul>
<li><p>Convince SIMRAN's father</p>
</li>
<li><p>Impress SIMRAN's mon</p>
</li>
<li><p>Fight with Villains</p>
</li>
</ul>
<p>Now if ANY ONE fails - then RAJ &amp; SIMRAN can't be together.</p>
<p>Only when ALL SUCCEED - then weeding happens.</p>
<p>And this is how exactly Promise.all() works.</p>
<pre><code class="language-javascript">let bauji = Promise.resolve("Bauji agreed");
let mom = Promise.resolve("Mom agreed");
let goons = Promise.resolve("Villains defeated");

Promise.all([bauji, mom, goons])
  .then(results =&gt; {
    console.log("Shaadi pakki:", results);
  })
  .catch(err =&gt; {
    console.log("Mission failed:", err);
  });
</code></pre>
<blockquote>
<ul>
<li><p>If ONE rejects - whole thing rejects.</p>
</li>
<li><p>This method returns array of results.</p>
</li>
</ul>
</blockquote>
<h2>Promise.allSettled()</h2>
<p>Now it is like RAJ wants to know :</p>
<ul>
<li><p>Who aggred</p>
</li>
<li><p>Who rejected</p>
</li>
</ul>
<blockquote>
<p>Even if someone says no, he still wants to know all outcomes.</p>
<p>And this is how Promise.allSettled() method works.</p>
</blockquote>
<p>Marriage may or may not happen - but we get full report of who aggred and who disagree. (So we can deal with them later 😈)</p>
<p>let bauji = Promise.resolve("Bauji agreed"); let mom = Promise.resolve("Mom agreed"); let fufaJi = Promise.reject("FufaJi said no");</p>
<pre><code class="language-javascript">let bauji = Promise.resolve("Bauji agreed");
let mom = Promise.resolve("Mom agreed");
let fufaJi = Promise.reject("FufaJi said no");

Promise.allSettled([bauji, mom, fufaJi])
  .then(results =&gt; {
    console.log(results);
  });
</code></pre>
<p>Output looks like :</p>
<pre><code class="language-javascript">[
  { status: "fulfilled", value: "Bauji agreed" },
  { status: "fulfilled", value: "Mom agreed" },
  { status: "rejected", reason: "fufaJi said no!" },
]
</code></pre>
<blockquote>
<p>This method never rejects.</p>
<p>Always gives status of all promises.</p>
</blockquote>
<h2>Promise.race()</h2>
<p>RAJ is running to catch the train &amp; SIMRAN is waiting.</p>
<p>Whoever happens FIRST decides the FATE.</p>
<ul>
<li><p>If RAJ reaches the train first - love wins</p>
</li>
<li><p>If TRAIN leaves the station first - love lost</p>
</li>
</ul>
<p>And this is how Promise.race() works.</p>
<p>First settled promise always wins. No matter it is resolved or rejected.</p>
<pre><code class="language-javascript">let raj = new Promise(resolve =&gt;
  setTimeout(() =&gt; resolve("Raj reached train"), 2000)
);

let train = new Promise(( reject) =&gt;
  setTimeout(() =&gt; reject("Train left 💔"), 1000)
);

Promise.race([raj, train])
  .then(res =&gt; console.log(res))
  .catch(err =&gt; console.log(err));
</code></pre>
<h2>Promise.any()</h2>
<p>RAJ tries to :</p>
<ul>
<li><p>Convince SIMRAN's father</p>
</li>
<li><p>Convince SIMRAN's mom</p>
</li>
<li><p>Convince SIMRAN's fufaJi</p>
</li>
</ul>
<p>Now situation got out to control. RAJ just need at least one persons approval to their relationship. IF any one of these aggrees then RAJ and SIMRAN can live happily. They just need one validation now.</p>
<p>And this is how Promise.any() works.</p>
<pre><code class="language-javascript">let p1 = Promise.reject("Bauji no");
let p2 = Promise.reject("Mom no");
let p3 = Promise.resolve("fufaJi helped");

Promise.any([p1, p2, p3])
  .then(res =&gt; console.log("Hope alive:", res))
  .catch(err =&gt; console.log("All rejected:", err));
</code></pre>
<p>This method resolves when FIRST fulfilled promise comes.</p>
<p>This method rejects only when all are rejected.</p>
<h2>Summary</h2>
<blockquote>
<p>At the end of the day, a Promise in JavaScript is simple - handle it properly, and it won't break your app… or your heart. I tried my best to keep the Hindi minimal so this article stays accessible to everyone . I hope you enjoyed the story.</p>
</blockquote>
<p>#chaicode #javascript #promise</p>
]]></content:encoded></item></channel></rss>