<?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[Sayantan Blogs]]></title><description><![CDATA[Sayantan Blogs]]></description><link>https://blogs.sayantanbal.in</link><generator>RSS for Node</generator><lastBuildDate>Sat, 02 May 2026 09:02:38 GMT</lastBuildDate><atom:link href="https://blogs.sayantanbal.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Kafka explained : The easy way]]></title><description><![CDATA[Well, this is always a hefty topic to understand—but the core idea behind it isn’t that complex. In fact, once you strip away the jargon, it’s surprisingly intuitive.
Kafka acts as a broker for messag]]></description><link>https://blogs.sayantanbal.in/kafka-explained-the-easy-way</link><guid isPermaLink="true">https://blogs.sayantanbal.in/kafka-explained-the-easy-way</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Tue, 28 Apr 2026 14:56:09 GMT</pubDate><content:encoded><![CDATA[<p>Well, this is always a hefty topic to understand—but the core idea behind it isn’t that complex. In fact, once you strip away the jargon, it’s surprisingly intuitive.</p>
<p>Kafka acts as a <strong>broker for messages</strong>, which is why it’s classified as a <strong>distributed event streaming platform</strong> (often loosely called a message broker, though it’s more powerful than traditional ones).</p>
<h2>Idea</h2>
<p>The core idea behind Kafka was simple:</p>
<blockquote>
<p><strong>Prevent servers from collapsing under massive load by decoupling data producers and consumers.</strong></p>
</blockquote>
<p>Instead of services directly talking to each other (tight coupling), Kafka introduces a middle layer that <strong>stores and distributes events efficiently</strong>.</p>
<p>It was engineered by LinkedIn in 2010 to handle high-throughput, real-time data ingestion and event processing—because existing systems couldn’t handle their scale.</p>
<p>It was developed by Jay Kreps, Jun Rao, and Neha Narkhede, open-sourced in 2011, and became a top-level Apache Software Foundation project in 2012 as Apache Kafka.</p>
<p>Kafka eventually became the <strong>de facto standard</strong> for high-throughput, low-latency event streaming—powering logs, analytics pipelines, microservices communication, and real-time systems globally.</p>
<h2>But Why Kafka Was Needed?</h2>
<p>Before Kafka, systems looked like this:</p>
<ul>
<li><p>Service A → directly calls Service B</p>
</li>
<li><p>Service B → directly calls Service C</p>
</li>
</ul>
<p>Problems:</p>
<ul>
<li><p>Tight coupling</p>
</li>
<li><p>System crashes under load</p>
</li>
<li><p>No buffering mechanism</p>
</li>
<li><p>Hard to scale</p>
</li>
</ul>
<p>Kafka solves this by acting as a <strong>central pipeline</strong>:</p>
<pre><code class="language-plaintext">Producers → Kafka → Consumers
</code></pre>
<p>Now:</p>
<ul>
<li><p>Producers just send data</p>
</li>
<li><p>Consumers read when ready</p>
</li>
<li><p>System becomes <strong>asynchronous and resilient</strong></p>
</li>
</ul>
<h2>Core Principles of Kafka</h2>
<p>When Kafka was designed, it relied on a few foundational assumptions:</p>
<h3>1. High Throughput Over Low Latency</h3>
<p>Kafka is optimised to handle <strong>millions of messages per second</strong> efficiently.</p>
<h3>2. Sequential Disk Writes</h3>
<p>Instead of random writes, Kafka appends messages to logs:</p>
<ul>
<li><p>Faster disk I/O</p>
</li>
<li><p>Better performance</p>
</li>
</ul>
<h3>3. Immutable Logs</h3>
<p>Once written, messages:</p>
<ul>
<li><p>Are <strong>not modified</strong></p>
</li>
<li><p>Are only appended and read</p>
</li>
</ul>
<h3>4. Pull-Based Consumption</h3>
<p>Consumers:</p>
<ul>
<li><p>Pull data at their own pace</p>
</li>
<li><p>Avoid overload</p>
</li>
</ul>
<h3>5. Partition-Based Scaling</h3>
<p>Topics are divided into partitions:</p>
<ul>
<li><p>Enables parallel processing</p>
</li>
<li><p>Horizontal scalability</p>
</li>
</ul>
<h2>Kafka Core Components</h2>
<h3>1. Producer</h3>
<ul>
<li><p>Sends messages to Kafka</p>
</li>
<li><p>Example: a backend service sending user activity</p>
</li>
</ul>
<h3>2. Broker</h3>
<ul>
<li><p>Kafka server that stores data</p>
</li>
<li><p>Handles read/write requests</p>
</li>
</ul>
<h3>3. Topic</h3>
<ul>
<li><p>Logical category of messages</p>
</li>
<li><p>Example: <code>user-signups</code>, <code>payments</code></p>
</li>
</ul>
<h3>4. Partition</h3>
<ul>
<li><p>Subdivision of a topic</p>
</li>
<li><p>Enables scaling and parallelism</p>
</li>
</ul>
<h3>5. Consumer</h3>
<ul>
<li>Reads messages from Kafka</li>
</ul>
<h3>6. Consumer Group</h3>
<ul>
<li><p>Multiple consumers working together</p>
</li>
<li><p>Each partition is consumed by only one consumer in a group</p>
</li>
</ul>
<h2>How Kafka Works (Simple Flow)</h2>
<ol>
<li><p>Producer sends message to a topic</p>
</li>
<li><p>Kafka stores it in a partition (append-only log)</p>
</li>
<li><p>Consumer reads from that partition using an offset</p>
</li>
<li><p>Message stays in Kafka for a configured retention period</p>
</li>
</ol>
<h2>Why Kafka Became So Popular</h2>
<ul>
<li><p>Handles <strong>real-time data streams</strong></p>
</li>
<li><p>Fault-tolerant and distributed</p>
</li>
<li><p>Scales horizontally</p>
</li>
<li><p>Decouples services</p>
</li>
<li><p>Works as a backbone for <strong>event-driven architecture</strong></p>
</li>
</ul>
<h2>Real-World Use Cases</h2>
<ul>
<li><p>Logging systems</p>
</li>
<li><p>Real-time analytics</p>
</li>
<li><p>Event-driven microservices</p>
</li>
<li><p>Fraud detection systems</p>
</li>
<li><p>Streaming pipelines (ETL)</p>
</li>
</ul>
<h2>The Problem: Kafka at Extreme Scale</h2>
<p>Kafka works incredibly well—but <strong>15 years later</strong>, its original assumptions are being pushed to the limit at LinkedIn-scale systems.</p>
<p>We’re talking about:</p>
<ul>
<li><p><strong>Trillions of daily messages</strong></p>
</li>
<li><p><strong>Multi-region deployments</strong></p>
</li>
<li><p><strong>Terabytes of metadata</strong></p>
</li>
<li><p><strong>Highly dynamic workloads needing auto-rebalancing</strong></p>
</li>
</ul>
<p>At this scale, new challenges emerge:</p>
<h3>1. Metadata Bottlenecks</h3>
<p>Kafka relies heavily on cluster metadata:</p>
<ul>
<li><p>Becomes large and complex</p>
</li>
<li><p>Hard to manage efficiently</p>
</li>
</ul>
<h3>2. Rebalancing Issues</h3>
<p>When consumers join/leave:</p>
<ul>
<li><p>Kafka needs to rebalance partitions</p>
</li>
<li><p>Causes latency spikes</p>
</li>
</ul>
<h3>3. Operational Complexity</h3>
<p>Running Kafka clusters at massive scale:</p>
<ul>
<li><p>Requires heavy tuning</p>
</li>
<li><p>Complex infrastructure management</p>
</li>
</ul>
<h3>4. Multi-Region Limitations</h3>
<p>Cross-region replication:</p>
<ul>
<li><p>Adds latency</p>
</li>
<li><p>Hard to maintain consistency</p>
</li>
</ul>
<h2>LinkedIn’s Shift: NorthGuard</h2>
<p>To address these challenges, LinkedIn is rethinking event streaming systems entirely with a new system called <strong>NorthGuard</strong>.</p>
<h3>What is NorthGuard?</h3>
<p>NorthGuard is LinkedIn’s next-generation event streaming architecture designed to:</p>
<ul>
<li><p>Handle <strong>extreme scale more efficiently</strong></p>
</li>
<li><p>Reduce operational overhead</p>
</li>
<li><p>Improve elasticity and rebalancing</p>
</li>
<li><p>Better support multi-region systems</p>
</li>
</ul>
<h2>What’s Changing?</h2>
<h3>1. Dynamic Scaling</h3>
<p>Kafka assumes relatively stable workloads.</p>
<p>NorthGuard:</p>
<ul>
<li><p>Adapts dynamically</p>
</li>
<li><p>Handles fluctuating traffic seamlessly</p>
</li>
</ul>
<h3>2. Improved Metadata Management</h3>
<p>Instead of massive centralized metadata:</p>
<ul>
<li><p>More efficient distribution</p>
</li>
<li><p>Better scalability</p>
</li>
</ul>
<h3>3. Faster Rebalancing</h3>
<p>Kafka rebalancing is expensive.</p>
<p>NorthGuard:</p>
<ul>
<li><p>Aims for near-zero disruption</p>
</li>
<li><p>Faster partition movement</p>
</li>
</ul>
<h3>4. Cloud-Native Thinking</h3>
<p>Kafka was designed pre-cloud era.</p>
<p>NorthGuard:</p>
<ul>
<li>Built with <strong>modern distributed systems + cloud infra in mind</strong></li>
</ul>
<h2>Key Takeaway</h2>
<p>Kafka is still incredibly powerful and widely used—but:</p>
<blockquote>
<p><strong>At extreme scale, even great systems need evolution.</strong></p>
</blockquote>
<p>Kafka solved:</p>
<ul>
<li><p>Decoupling</p>
</li>
<li><p>High-throughput streaming</p>
</li>
<li><p>Fault tolerance</p>
</li>
</ul>
<p>NorthGuard is solving:</p>
<ul>
<li><p>Elastic scaling</p>
</li>
<li><p>Massive metadata</p>
</li>
<li><p>Global distribution challenges</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[The Node.js Event Loop Explained]]></title><description><![CDATA[Introduction
JavaScript was originally designed to run inside browsers, handling user interactions like clicks and form submissions. When Node.js brought JavaScript to the server, it introduced a chal]]></description><link>https://blogs.sayantanbal.in/the-node-js-event-loop-explained</link><guid isPermaLink="true">https://blogs.sayantanbal.in/the-node-js-event-loop-explained</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 16:26:00 GMT</pubDate><content:encoded><![CDATA[<h2>Introduction</h2>
<p>JavaScript was originally designed to run inside browsers, handling user interactions like clicks and form submissions. When Node.js brought JavaScript to the server, it introduced a challenge:</p>
<blockquote>
<p>How can a <strong>single-threaded environment</strong> handle thousands of requests efficiently?</p>
</blockquote>
<p>The answer lies in one of Node.js’s most important concepts — <strong>the Event Loop</strong>.</p>
<hr />
<h2>The Single-Thread Limitation</h2>
<p>Unlike traditional backend technologies (like Java or PHP), Node.js runs on a <strong>single thread</strong>.</p>
<p>This means:</p>
<ul>
<li><p>Only <strong>one piece of code executes at a time</strong></p>
</li>
<li><p>No parallel execution like multi-threaded systems</p>
</li>
</ul>
<p>At first glance, this sounds like a bottleneck.</p>
<p>If one task blocks the thread (e.g., reading a file or calling an API), everything else would have to wait.</p>
<p>So how does Node.js still handle thousands of users?</p>
<p>👉 This is exactly why the <strong>event loop exists</strong>.</p>
<hr />
<h2>What is the Event Loop?</h2>
<p>The <strong>event loop</strong> is essentially a <strong>task manager</strong>.</p>
<p>It continuously checks:</p>
<ol>
<li><p>Is the main thread free?</p>
</li>
<li><p>Are there any tasks waiting to be executed?</p>
</li>
</ol>
<p>If both conditions are satisfied, it takes a task from a queue and executes it.</p>
<h3>Simple Analogy</h3>
<p>Think of it like a <strong>restaurant waiter</strong>:</p>
<ul>
<li><p>The waiter (event loop) takes orders (tasks)</p>
</li>
<li><p>Sends them to the kitchen (background workers)</p>
</li>
<li><p>Comes back to serve completed dishes (callbacks)</p>
</li>
</ul>
<p>The waiter doesn’t cook — just manages flow efficiently.</p>
<hr />
<h2>Why Node.js Needs the Event Loop</h2>
<p>Because Node.js is single-threaded:</p>
<ul>
<li><p>It <strong>cannot afford to block execution</strong></p>
</li>
<li><p>It must <strong>delegate slow operations</strong></p>
</li>
</ul>
<p>So instead of waiting:</p>
<ul>
<li><p>Node.js <strong>offloads tasks</strong> like file reading, database queries, or API calls</p>
</li>
<li><p>Continues handling other requests</p>
</li>
<li><p>Comes back when the task is done</p>
</li>
</ul>
<p>Without the event loop:</p>
<ul>
<li><p>Every request would block others</p>
</li>
<li><p>Performance would collapse under load</p>
</li>
</ul>
<hr />
<h2>Call Stack vs Task Queue (Conceptual)</h2>
<p>To understand the event loop, you need two core components:</p>
<h3>1. Call Stack</h3>
<ul>
<li><p>Where code is executed</p>
</li>
<li><p>Works in <strong>LIFO (Last In, First Out)</strong> manner</p>
</li>
<li><p>Only one function runs at a time</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="language-plaintext">main() → fetchData() → processData()
</code></pre>
<hr />
<h3>2. Task Queue (Callback Queue)</h3>
<ul>
<li><p>Stores <strong>completed async tasks</strong></p>
</li>
<li><p>Works in <strong>FIFO (First In, First Out)</strong></p>
</li>
</ul>
<hr />
<h3>How the Event Loop Connects Them</h3>
<p>The event loop continuously:</p>
<ol>
<li><p>Checks if the <strong>call stack is empty</strong></p>
</li>
<li><p>If yes → takes the <strong>first task from the queue</strong></p>
</li>
<li><p>Pushes it into the call stack</p>
</li>
</ol>
<hr />
<h2>How Async Operations are Handled</h2>
<p>Let’s say you write:</p>
<pre><code class="language-js">setTimeout(() =&gt; {
  console.log("Hello after 2 seconds");
}, 2000);
</code></pre>
<p>What happens internally?</p>
<ol>
<li><p>Timer is registered</p>
</li>
<li><p>Node.js <strong>does not wait</strong></p>
</li>
<li><p>Timer runs in background</p>
</li>
<li><p>After 2 seconds → callback goes to task queue</p>
</li>
<li><p>Event loop picks it when stack is free</p>
</li>
</ol>
<p>👉 This is <strong>non-blocking behavior</strong></p>
<hr />
<h2>Timers vs I/O Callbacks (High-Level)</h2>
<p>Node.js handles different types of async operations differently.</p>
<h3>Timers</h3>
<ul>
<li><p>Functions like <code>setTimeout</code>, <code>setInterval</code></p>
</li>
<li><p>Scheduled after a certain delay</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="language-js">setTimeout(() =&gt; console.log("Timer done"), 1000);
</code></pre>
<hr />
<h3>I/O Callbacks</h3>
<ul>
<li><p>File system operations</p>
</li>
<li><p>Network requests</p>
</li>
<li><p>Database queries</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="language-js">fs.readFile("file.txt", () =&gt; {
  console.log("File read complete");
});
</code></pre>
<hr />
<h3>Key Difference</h3>
<table>
<thead>
<tr>
<th>Type</th>
<th>Triggered By</th>
<th>Example Use Case</th>
</tr>
</thead>
<tbody><tr>
<td>Timers</td>
<td>Time delay</td>
<td>setTimeout</td>
</tr>
<tr>
<td>I/O</td>
<td>External operations</td>
<td>File/database/network</td>
</tr>
</tbody></table>
<p>Both eventually: ➡️ Push callbacks to the queue ➡️ Event loop executes them</p>
<hr />
<h2>Event Loop and Scalability</h2>
<p>This is where Node.js shines.</p>
<h3>Traditional Model (Blocking)</h3>
<ul>
<li><p>One thread per request</p>
</li>
<li><p>High memory usage</p>
</li>
<li><p>Limited scalability</p>
</li>
</ul>
<hr />
<h3>Node.js Model (Event Loop)</h3>
<ul>
<li><p>Single thread</p>
</li>
<li><p>Non-blocking I/O</p>
</li>
<li><p>Handles <strong>thousands of concurrent requests</strong></p>
</li>
</ul>
<hr />
<h3>Why It Works</h3>
<p>Because Node.js:</p>
<ul>
<li><p>Doesn’t wait for slow operations</p>
</li>
<li><p>Keeps the thread free</p>
</li>
<li><p>Uses the event loop to manage execution</p>
</li>
</ul>
<p>👉 Result: <strong>High throughput with minimal resources</strong></p>
<hr />
<h2>Real-World Example</h2>
<p>Imagine a server handling 3 requests:</p>
<ol>
<li><p>Fetch user data (DB call)</p>
</li>
<li><p>Read file</p>
</li>
<li><p>Send response</p>
</li>
</ol>
<h3>Traditional Server</h3>
<ul>
<li><p>Request 1 blocks everything</p>
</li>
<li><p>Others wait</p>
</li>
</ul>
<hr />
<h3>Node.js with Event Loop</h3>
<ul>
<li><p>Delegates DB + file tasks</p>
</li>
<li><p>Immediately handles next request</p>
</li>
<li><p>Executes callbacks when ready</p>
</li>
</ul>
<p>👉 All requests are handled efficiently without blocking</p>
<hr />
<h2>Key Takeaways</h2>
<ul>
<li><p>Node.js is <strong>single-threaded</strong>, but not slow</p>
</li>
<li><p>The <strong>event loop</strong> enables concurrency</p>
</li>
<li><p>It works by:</p>
<ul>
<li><p>Monitoring the call stack</p>
</li>
<li><p>Managing the task queue</p>
</li>
</ul>
</li>
<li><p>Async operations are:</p>
<ul>
<li><p>Delegated</p>
</li>
<li><p>Returned via callbacks</p>
</li>
</ul>
</li>
<li><p>This model makes Node.js <strong>highly scalable</strong></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Blocking vs Non-Blocking Code in Node.js]]></title><description><![CDATA[When building backend systems, one of the most important concepts to understand is how your server handles tasks. In Node.js, this comes down to blocking vs non-blocking code — a core reason why Node.]]></description><link>https://blogs.sayantanbal.in/blocking-vs-non-blocking-code-in-node-js</link><guid isPermaLink="true">https://blogs.sayantanbal.in/blocking-vs-non-blocking-code-in-node-js</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 16:25:00 GMT</pubDate><content:encoded><![CDATA[<p>When building backend systems, one of the most important concepts to understand is how your server handles tasks. In Node.js, this comes down to <strong>blocking vs non-blocking code</strong> — a core reason why Node.js is fast and scalable.</p>
<p>Let’s break it down in a simple, practical way.</p>
<hr />
<h2>🚧 What is Blocking Code?</h2>
<p><strong>Blocking code</strong> means: 👉 The program <strong>waits</strong> for a task to finish before moving to the next line.</p>
<h3>Example (Synchronous / Blocking)</h3>
<pre><code class="language-js">const fs = require("fs");

const data = fs.readFileSync("file.txt", "utf-8");
console.log(data);

console.log("Next line");
</code></pre>
<h3>What happens here:</h3>
<ol>
<li><p>Node starts reading the file</p>
</li>
<li><p>It <strong>pauses everything else</strong></p>
</li>
<li><p>Only after reading completes → it prints <code>"Next line"</code></p>
</li>
</ol>
<h3>❗ Problem</h3>
<p>If the file is large or slow to access:</p>
<ul>
<li><p>The entire server is stuck</p>
</li>
<li><p>No other user request can be processed</p>
</li>
</ul>
<hr />
<h2>⚡ What is Non-Blocking Code?</h2>
<p><strong>Non-blocking code</strong> means: 👉 The program <strong>does not wait</strong> — it moves forward and handles the result later.</p>
<h3>Example (Asynchronous / Non-Blocking)</h3>
<pre><code class="language-js">const fs = require("fs");

fs.readFile("file.txt", "utf-8", (err, data) =&gt; {
  console.log(data);
});

console.log("Next line");
</code></pre>
<h3>What happens here:</h3>
<ol>
<li><p>File read starts in background</p>
</li>
<li><p>Node <strong>immediately moves on</strong></p>
</li>
<li><p><code>"Next line"</code> prints first</p>
</li>
<li><p>File result prints later</p>
</li>
</ol>
<hr />
<h2>🧠 Simple Analogy</h2>
<p>Think of it like ordering food:</p>
<h3>Blocking</h3>
<ul>
<li><p>You go to a restaurant</p>
</li>
<li><p>Stand at the counter until your food is ready</p>
</li>
<li><p>Do nothing else</p>
</li>
</ul>
<h3>Non-Blocking</h3>
<ul>
<li><p>You order food</p>
</li>
<li><p>Sit with friends / do other work</p>
</li>
<li><p>Get notified when food is ready</p>
</li>
</ul>
<p>👉 Node.js works like the second scenario.</p>
<hr />
<h2>🐢 Why Blocking Code Slows Down Servers</h2>
<p>Node.js uses a <strong>single-threaded event loop</strong>.</p>
<p>That means:</p>
<ul>
<li><p>Only one main thread handles all requests</p>
</li>
<li><p>If one request blocks → everything else waits</p>
</li>
</ul>
<h3>Real Impact:</h3>
<p>If 100 users hit your server:</p>
<ul>
<li><p>Blocking → requests handled one-by-one ❌</p>
</li>
<li><p>Non-blocking → requests handled concurrently ✅</p>
</li>
</ul>
<hr />
<h2>🔄 Async Operations in Node.js</h2>
<p>Node.js is designed around <strong>asynchronous (async) operations</strong>, such as:</p>
<ul>
<li><p>File system operations (<code>fs</code>)</p>
</li>
<li><p>Database queries</p>
</li>
<li><p>API calls</p>
</li>
<li><p>Network requests</p>
</li>
</ul>
<p>These tasks are:</p>
<ul>
<li><p>Delegated to background workers</p>
</li>
<li><p>Returned via callbacks, promises, or async/await</p>
</li>
</ul>
<hr />
<h2>📂 Real-World Example: File Handling</h2>
<h3>Blocking Version</h3>
<pre><code class="language-js">app.get("/", (req, res) =&gt; {
  const data = fs.readFileSync("largeFile.txt", "utf-8");
  res.send(data);
});
</code></pre>
<p>🔴 Problem:</p>
<ul>
<li><p>Each request waits for file read</p>
</li>
<li><p>Server becomes slow under load</p>
</li>
</ul>
<hr />
<h3>Non-Blocking Version</h3>
<pre><code class="language-js">app.get("/", (req, res) =&gt; {
  fs.readFile("largeFile.txt", "utf-8", (err, data) =&gt; {
    res.send(data);
  });
});
</code></pre>
<p>🟢 Advantage:</p>
<ul>
<li><p>Server continues handling other requests</p>
</li>
<li><p>Much better performance</p>
</li>
</ul>
<hr />
<h2>🗄️ Real-World Example: Database Calls</h2>
<h3>Blocking (Bad Practice)</h3>
<pre><code class="language-js">const user = db.getUserSync(id);
</code></pre>
<h3>Non-Blocking (Correct)</h3>
<pre><code class="language-js">db.getUser(id).then(user =&gt; {
  console.log(user);
});
</code></pre>
<p>or</p>
<pre><code class="language-js">const user = await db.getUser(id);
</code></pre>
<p>👉 Database operations are slow — always keep them async.</p>
<hr />
<h2>⚖️ Blocking vs Non-Blocking Summary</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Blocking Code ❌</th>
<th>Non-Blocking Code ✅</th>
</tr>
</thead>
<tbody><tr>
<td>Execution</td>
<td>Waits</td>
<td>Continues immediately</td>
</tr>
<tr>
<td>Performance</td>
<td>Slow</td>
<td>Fast</td>
</tr>
<tr>
<td>Scalability</td>
<td>Poor</td>
<td>High</td>
</tr>
<tr>
<td>Use Case</td>
<td>Rare (startup scripts)</td>
<td>Almost everywhere in Node</td>
</tr>
</tbody></table>
<hr />
<h2>🎯 When (If Ever) to Use Blocking?</h2>
<p>Blocking code is acceptable when:</p>
<ul>
<li><p>Running startup scripts</p>
</li>
<li><p>CLI tools</p>
</li>
<li><p>One-time operations (not handling users)</p>
</li>
</ul>
<p>👉 Never use blocking code in production servers.</p>
<hr />
<h2>🚀 Final Takeaway</h2>
<ul>
<li><p>Node.js shines because of <strong>non-blocking architecture</strong></p>
</li>
<li><p>Blocking code defeats its purpose</p>
</li>
<li><p>Always prefer:</p>
<ul>
<li><p>Callbacks</p>
</li>
<li><p>Promises</p>
</li>
<li><p><code>async/await</code></p>
</li>
</ul>
</li>
</ul>
<p>👉 If your server feels slow, chances are you're accidentally blocking the event loop.</p>
<hr />
]]></content:encoded></item><item><title><![CDATA[REST API Design Made Simple with Express.js]]></title><description><![CDATA[Building APIs is a core skill for any backend or full-stack developer. If you're working with Node.js, understanding how to design clean and scalable REST APIs using Express.js is essential.
This guid]]></description><link>https://blogs.sayantanbal.in/rest-api-design-made-simple-with-express-js</link><guid isPermaLink="true">https://blogs.sayantanbal.in/rest-api-design-made-simple-with-express-js</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 16:23:19 GMT</pubDate><content:encoded><![CDATA[<p>Building APIs is a core skill for any backend or full-stack developer. If you're working with Node.js, understanding how to design clean and scalable REST APIs using Express.js is essential.</p>
<p>This guide breaks it down in a simple, practical way.</p>
<hr />
<h2>🚀 What is a REST API?</h2>
<p>A <strong>REST API (Representational State Transfer)</strong> is a way for different systems (usually a client and a server) to communicate over HTTP.</p>
<p>Think of it like this:</p>
<ul>
<li><p>The <strong>client</strong> (browser, mobile app) sends a request</p>
</li>
<li><p>The <strong>server</strong> processes it</p>
</li>
<li><p>The <strong>server</strong> sends back a response</p>
</li>
</ul>
<p>👉 Example:</p>
<ul>
<li>You open Instagram → app requests data → server sends posts</li>
</ul>
<p>So essentially:</p>
<blockquote>
<p>APIs are the <strong>communication bridge</strong> between client and server.</p>
</blockquote>
<hr />
<h2>📦 What are Resources in REST?</h2>
<p>In REST architecture, everything is treated as a <strong>resource</strong>.</p>
<p>A resource is simply:</p>
<blockquote>
<p>Any data you want to expose via your API</p>
</blockquote>
<p>Examples:</p>
<ul>
<li><p>Users → <code>/users</code></p>
</li>
<li><p>Products → <code>/products</code></p>
</li>
<li><p>Orders → <code>/orders</code></p>
</li>
</ul>
<p>Each resource is accessed via a <strong>URL endpoint</strong>.</p>
<hr />
<h2>🔧 HTTP Methods (Core of REST)</h2>
<p>REST APIs use HTTP methods to define actions on resources.</p>
<h3>1. GET → Fetch Data</h3>
<p>Used to retrieve data from the server.</p>
<pre><code class="language-http">GET /users
</code></pre>
<p>👉 Fetch all users</p>
<hr />
<h3>2. POST → Create Data</h3>
<p>Used to create a new resource.</p>
<pre><code class="language-http">POST /users
</code></pre>
<p>👉 Create a new user</p>
<hr />
<h3>3. PUT → Update Data</h3>
<p>Used to update an existing resource (usually full update).</p>
<pre><code class="language-http">PUT /users/1
</code></pre>
<p>👉 Update user with ID = 1</p>
<hr />
<h3>4. DELETE → Remove Data</h3>
<p>Used to delete a resource.</p>
<pre><code class="language-http">DELETE /users/1
</code></pre>
<p>👉 Delete user with ID = 1</p>
<hr />
<h2>📊 Status Codes Basics</h2>
<p>Status codes tell the client what happened with the request.</p>
<h3>Common ones you should know:</h3>
<ul>
<li><p><strong>200 OK</strong> → Request successful</p>
</li>
<li><p><strong>201 Created</strong> → Resource created successfully</p>
</li>
<li><p><strong>400 Bad Request</strong> → Client error</p>
</li>
<li><p><strong>404 Not Found</strong> → Resource doesn’t exist</p>
</li>
<li><p><strong>500 Internal Server Error</strong> → Server failed</p>
</li>
</ul>
<p>👉 Example:</p>
<pre><code class="language-js">res.status(200).json(users);
</code></pre>
<hr />
<h2>🛣️ Designing RESTful Routes</h2>
<p>A good REST API follows <strong>clean and predictable naming conventions</strong>.</p>
<h3>Rules:</h3>
<ul>
<li><p>Use <strong>nouns</strong>, not verbs</p>
</li>
<li><p>Keep URLs <strong>plural</strong></p>
</li>
<li><p>Use <strong>IDs</strong> for specific resources</p>
</li>
</ul>
<hr />
<h2>👨‍💻 Example: Users Resource</h2>
<p>Let’s design a simple <code>users</code> API using Express.js.</p>
<h3>Setup</h3>
<pre><code class="language-js">const express = require("express");
const app = express();

app.use(express.json());
</code></pre>
<hr />
<h3>Routes</h3>
<h4>Get all users</h4>
<pre><code class="language-js">app.get("/users", (req, res) =&gt; {
  res.status(200).json({ message: "Get all users" });
});
</code></pre>
<h4>Get single user</h4>
<pre><code class="language-js">app.get("/users/:id", (req, res) =&gt; {
  res.status(200).json({ message: `Get user ${req.params.id}` });
});
</code></pre>
<h4>Create user</h4>
<pre><code class="language-js">app.post("/users", (req, res) =&gt; {
  res.status(201).json({ message: "User created" });
});
</code></pre>
<h4>Update user</h4>
<pre><code class="language-js">app.put("/users/:id", (req, res) =&gt; {
  res.status(200).json({ message: `User ${req.params.id} updated` });
});
</code></pre>
<h4>Delete user</h4>
<pre><code class="language-js">app.delete("/users/:id", (req, res) =&gt; {
  res.status(200).json({ message: `User ${req.params.id} deleted` });
});
</code></pre>
<hr />
<h2>🧠 Key Design Principles (Keep This in Mind)</h2>
<ul>
<li><p>Keep routes <strong>consistent and predictable</strong></p>
</li>
<li><p>Use correct <strong>HTTP methods</strong></p>
</li>
<li><p>Return meaningful <strong>status codes</strong></p>
</li>
<li><p>Separate logic (routes vs controllers in real apps)</p>
</li>
<li><p>Think in terms of <strong>resources, not actions</strong></p>
</li>
</ul>
<hr />
<h2>🔚 Final Thoughts</h2>
<p>REST API design is not about complexity — it's about <strong>clarity and consistency</strong>.</p>
<p>If your API:</p>
<ul>
<li><p>Uses proper HTTP methods</p>
</li>
<li><p>Has clean route naming</p>
</li>
<li><p>Returns correct status codes</p>
</li>
</ul>
<p>👉 You're already ahead of most beginners.</p>
<p>Once you're comfortable with this, the next step is:</p>
<ul>
<li><p>Adding authentication (JWT)</p>
</li>
<li><p>Connecting databases (MongoDB)</p>
</li>
<li><p>Structuring scalable backend systems</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Why Node.js is Perfect for Building Fast Web Applications]]></title><description><![CDATA[When developers talk about speed in web applications, they’re not just referring to raw execution time—they mean how efficiently a system can handle multiple users, process requests, and respond witho]]></description><link>https://blogs.sayantanbal.in/why-node-js-is-perfect-for-building-fast-web-applications</link><guid isPermaLink="true">https://blogs.sayantanbal.in/why-node-js-is-perfect-for-building-fast-web-applications</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 16:21:47 GMT</pubDate><content:encoded><![CDATA[<p>When developers talk about speed in web applications, they’re not just referring to raw execution time—they mean how efficiently a system can handle multiple users, process requests, and respond without delays. This is exactly where Node.js stands out.</p>
<p>In this article, we’ll break down <strong>why Node.js is considered fast</strong>, not through benchmarks, but by understanding how it behaves under the hood.</p>
<hr />
<h2>🚀 What Makes Node.js Fast?</h2>
<p>Node.js is fast because of its <strong>architecture</strong>, not magic.</p>
<p>At its core:</p>
<ul>
<li><p>It uses the <strong>V8 JavaScript engine</strong> (same as Chrome)</p>
</li>
<li><p>It follows a <strong>non-blocking, asynchronous execution model</strong></p>
</li>
<li><p>It is built on an <strong>event-driven architecture</strong></p>
</li>
<li><p>It runs on a <strong>single-threaded event loop</strong></p>
</li>
</ul>
<p>Instead of handling one request at a time (like traditional servers), Node.js can handle <strong>thousands of concurrent requests efficiently</strong>.</p>
<hr />
<h2>🔄 Understanding Non-Blocking I/O</h2>
<h3>Blocking (Traditional Approach)</h3>
<p>Imagine a server handling requests like this:</p>
<ol>
<li><p>User requests data</p>
</li>
<li><p>Server queries database</p>
</li>
<li><p>Server <em>waits</em> for response</p>
</li>
<li><p>Only then handles the next request</p>
</li>
</ol>
<p>👉 Problem: While waiting, the server is <strong>idle but blocked</strong></p>
<hr />
<h3>Non-Blocking (Node.js Approach)</h3>
<p>Node.js does something smarter:</p>
<ol>
<li><p>User requests data</p>
</li>
<li><p>Server sends database request</p>
</li>
<li><p>Moves on to handle other requests immediately</p>
</li>
<li><p>When data arrives → callback executes</p>
</li>
</ol>
<p>👉 Result: No waiting. The server stays <strong>busy and efficient</strong></p>
<hr />
<h2>🍽️ Restaurant Analogy (Async Handling)</h2>
<p>Think of a restaurant:</p>
<h3>❌ Blocking Model</h3>
<ul>
<li><p>One waiter</p>
</li>
<li><p>Takes one order</p>
</li>
<li><p>Goes to kitchen</p>
</li>
<li><p>Waits until food is ready</p>
</li>
<li><p>Serves it</p>
</li>
<li><p>Then takes next order</p>
</li>
</ul>
<p>Slow. Inefficient.</p>
<hr />
<h3>✅ Node.js Model</h3>
<ul>
<li><p>One waiter</p>
</li>
<li><p>Takes orders from multiple tables</p>
</li>
<li><p>Hands them to kitchen</p>
</li>
<li><p>Keeps taking more orders</p>
</li>
<li><p>Serves food when ready</p>
</li>
</ul>
<p>Efficient. Scalable.</p>
<p>👉 Node.js is like the second waiter.</p>
<hr />
<h2>⚡ Event-Driven Architecture</h2>
<p>Node.js operates on <strong>events</strong>.</p>
<p>Instead of continuously checking for updates, it reacts when something happens.</p>
<p>Examples of events:</p>
<ul>
<li><p>HTTP request received</p>
</li>
<li><p>File read completed</p>
</li>
<li><p>Database response returned</p>
</li>
</ul>
<h3>How it works:</h3>
<ul>
<li><p>Events are placed in a queue</p>
</li>
<li><p>The <strong>event loop</strong> processes them one by one</p>
</li>
<li><p>Associated callback functions execute</p>
</li>
</ul>
<p>👉 This avoids unnecessary CPU usage and improves responsiveness.</p>
<hr />
<h2>🧵 Single-Threaded Model (But Still Concurrent)</h2>
<p>At first glance, this sounds like a limitation.</p>
<blockquote>
<p>“Single-threaded? Then how is it fast?”</p>
</blockquote>
<p>Here’s the key:</p>
<ul>
<li><p>Node.js uses <strong>one main thread</strong></p>
</li>
<li><p>But delegates heavy work (I/O, file system, network) to background systems</p>
</li>
<li><p>The main thread only handles <strong>coordination</strong></p>
</li>
</ul>
<p>👉 So instead of multiple threads competing, Node.js:</p>
<ul>
<li><p>Avoids thread overhead</p>
</li>
<li><p>Avoids context switching</p>
</li>
<li><p>Remains lightweight</p>
</li>
</ul>
<hr />
<h2>🔁 Concurrency vs Parallelism (Simple Explanation)</h2>
<ul>
<li><p><strong>Concurrency</strong> = Handling many tasks at once (not necessarily simultaneously)</p>
</li>
<li><p><strong>Parallelism</strong> = Running multiple tasks at the exact same time</p>
</li>
</ul>
<h3>Node.js:</h3>
<ul>
<li><p>Focuses on <strong>concurrency</strong></p>
</li>
<li><p>Uses async operations to handle multiple users efficiently</p>
</li>
</ul>
<h3>Example:</h3>
<ul>
<li><p>100 users request data</p>
</li>
<li><p>Node.js doesn’t process one-by-one</p>
</li>
<li><p>It manages all requests together without blocking</p>
</li>
</ul>
<hr />
<h2>📍 Where Node.js Performs Best</h2>
<p>Node.js shines in scenarios that are:</p>
<h3>1. I/O Heavy Applications</h3>
<ul>
<li><p>APIs</p>
</li>
<li><p>Database-driven apps</p>
</li>
<li><p>File uploads/downloads</p>
</li>
</ul>
<h3>2. Real-Time Applications</h3>
<ul>
<li><p>Chat apps</p>
</li>
<li><p>Live notifications</p>
</li>
<li><p>Gaming servers</p>
</li>
</ul>
<h3>3. Streaming Applications</h3>
<ul>
<li><p>Video/audio streaming</p>
</li>
<li><p>Data streaming pipelines</p>
</li>
</ul>
<h3>4. Microservices Architecture</h3>
<ul>
<li><p>Lightweight services</p>
</li>
<li><p>Fast communication between services</p>
</li>
</ul>
<hr />
<h2>❗ Where Node.js is NOT Ideal</h2>
<p>For balance:</p>
<p>Node.js is <strong>not best for CPU-heavy tasks</strong> like:</p>
<ul>
<li><p>Image processing</p>
</li>
<li><p>Machine learning computations</p>
</li>
<li><p>Complex data transformations</p>
</li>
</ul>
<p>👉 Because heavy computation blocks the single thread.</p>
<hr />
<h2>🏢 Real-World Companies Using Node.js</h2>
<p>Many large-scale companies rely on Node.js:</p>
<ul>
<li><p>Netflix → Streaming backend</p>
</li>
<li><p>LinkedIn → Backend services</p>
</li>
<li><p>Uber → Real-time ride system</p>
</li>
<li><p>PayPal → Payment processing APIs</p>
</li>
<li><p>Walmart → High-traffic e-commerce systems</p>
</li>
</ul>
<p>👉 These companies chose Node.js for <strong>scalability and performance under load</strong></p>
<hr />
<h2>🔍 Blocking vs Non-Blocking (Quick Comparison)</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Blocking Model</th>
<th>Node.js (Non-Blocking)</th>
</tr>
</thead>
<tbody><tr>
<td>Request Handling</td>
<td>One at a time</td>
<td>Multiple concurrently</td>
</tr>
<tr>
<td>Waiting Time</td>
<td>High</td>
<td>Minimal</td>
</tr>
<tr>
<td>Resource Usage</td>
<td>Inefficient</td>
<td>Efficient</td>
</tr>
<tr>
<td>Scalability</td>
<td>Limited</td>
<td>High</td>
</tr>
</tbody></table>
<hr />
<h2>🧠 Final Thoughts</h2>
<p>Node.js is fast not because it executes code faster, but because it <strong>handles work smarter</strong>.</p>
<p>Its non-blocking, event-driven architecture allows it to:</p>
<ul>
<li><p>Handle massive concurrent traffic</p>
</li>
<li><p>Stay responsive under load</p>
</li>
<li><p>Use system resources efficiently</p>
</li>
</ul>
<p>If your application involves <strong>real-time communication, APIs, or high concurrency</strong>, Node.js is one of the best choices available.</p>
]]></content:encoded></item><item><title><![CDATA[What is Middleware in Express and How It Works]]></title><description><![CDATA[Introduction
When building backend applications using Express.js, one of the most important concepts you’ll encounter is middleware. Middleware is what gives Express its flexibility and power.
At a hi]]></description><link>https://blogs.sayantanbal.in/what-is-middleware-in-express-and-how-it-works</link><guid isPermaLink="true">https://blogs.sayantanbal.in/what-is-middleware-in-express-and-how-it-works</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 16:20:24 GMT</pubDate><content:encoded><![CDATA[<h2>Introduction</h2>
<p>When building backend applications using Express.js, one of the most important concepts you’ll encounter is <strong>middleware</strong>. Middleware is what gives Express its flexibility and power.</p>
<p>At a high level, middleware acts like a <strong>checkpoint system</strong> between a client request and the server response.</p>
<hr />
<h2>What is Middleware in Express?</h2>
<p>Middleware is simply a <strong>function</strong> that has access to:</p>
<ul>
<li><p><code>req</code> (request object)</p>
</li>
<li><p><code>res</code> (response object)</p>
</li>
<li><p><code>next</code> (function to pass control)</p>
</li>
</ul>
<h3>Basic Syntax</h3>
<pre><code class="language-js">function middleware(req, res, next) {
  console.log("Middleware executed");
  next();
}
</code></pre>
<p>👉 Middleware can:</p>
<ul>
<li><p>Modify request/response</p>
</li>
<li><p>End the request-response cycle</p>
</li>
<li><p>Call the next middleware</p>
</li>
</ul>
<hr />
<h2>Where Middleware Sits in the Request Lifecycle</h2>
<p>Think of Express as a <strong>pipeline</strong>:</p>
<pre><code class="language-plaintext">Client Request → Middleware → Middleware → Route Handler → Response
</code></pre>
<p>Each middleware processes the request step by step before reaching the final route handler.</p>
<h3>Example Flow</h3>
<pre><code class="language-js">app.use((req, res, next) =&gt; {
  console.log("Step 1");
  next();
});

app.use((req, res, next) =&gt; {
  console.log("Step 2");
  next();
});

app.get("/", (req, res) =&gt; {
  res.send("Final Response");
});
</code></pre>
<h3>Execution Order</h3>
<pre><code class="language-plaintext">Step 1 → Step 2 → Route Handler → Response
</code></pre>
<hr />
<h2>Types of Middleware in Express</h2>
<h3>1. Application-Level Middleware</h3>
<p>These are bound to the entire app using <code>app.use()</code>.</p>
<pre><code class="language-js">app.use((req, res, next) =&gt; {
  console.log("App-level middleware");
  next();
});
</code></pre>
<p>✔ Runs on every request (unless restricted by path)</p>
<hr />
<h3>2. Router-Level Middleware</h3>
<p>Used with Express routers (<code>express.Router()</code>).</p>
<pre><code class="language-js">const router = express.Router();

router.use((req, res, next) =&gt; {
  console.log("Router middleware");
  next();
});

app.use("/api", router);
</code></pre>
<p>✔ Only runs for specific route groups (<code>/api</code> here)</p>
<hr />
<h3>3. Built-in Middleware</h3>
<p>Express provides some ready-made middleware:</p>
<ul>
<li><p><code>express.json()</code> → Parses JSON body</p>
</li>
<li><p><code>express.urlencoded()</code> → Parses form data</p>
</li>
<li><p><code>express.static()</code> → Serves static files</p>
</li>
</ul>
<pre><code class="language-js">app.use(express.json());
</code></pre>
<p>✔ Saves time—no need to write common logic manually</p>
<hr />
<h2>Execution Order of Middleware</h2>
<p>Middleware executes <strong>in the order it is defined</strong>.</p>
<pre><code class="language-js">app.use((req, res, next) =&gt; {
  console.log("First");
  next();
});

app.use((req, res, next) =&gt; {
  console.log("Second");
  next();
});
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">First
Second
</code></pre>
<p>⚠️ Important: If <code>next()</code> is not called, the request <strong>will hang</strong>.</p>
<hr />
<h2>Role of <code>next()</code> Function</h2>
<p><code>next()</code> is what <strong>moves the request forward</strong> in the pipeline.</p>
<h3>Without next()</h3>
<pre><code class="language-js">app.use((req, res, next) =&gt; {
  console.log("Stops here");
});
</code></pre>
<p>❌ Request never reaches route handler → client hangs</p>
<hr />
<h3>With next()</h3>
<pre><code class="language-js">app.use((req, res, next) =&gt; {
  console.log("Continue");
  next();
});
</code></pre>
<p>✔ Execution continues</p>
<hr />
<h3>Ending Response in Middleware</h3>
<pre><code class="language-js">app.use((req, res, next) =&gt; {
  res.send("Response from middleware");
});
</code></pre>
<p>✔ No need to call <code>next()</code> because response is already sent</p>
<hr />
<h2>Real-World Examples of Middleware</h2>
<h3>1. Logging Middleware</h3>
<pre><code class="language-js">app.use((req, res, next) =&gt; {
  console.log(`\({req.method} \){req.url}`);
  next();
});
</code></pre>
<p>✔ Helps track incoming requests</p>
<hr />
<h3>2. Authentication Middleware</h3>
<pre><code class="language-js">function auth(req, res, next) {
  const isLoggedIn = true;

  if (!isLoggedIn) {
    return res.status(401).send("Unauthorized");
  }

  next();
}

app.get("/dashboard", auth, (req, res) =&gt; {
  res.send("Welcome to dashboard");
});
</code></pre>
<p>✔ Protects routes</p>
<hr />
<h3>3. Request Validation Middleware</h3>
<pre><code class="language-js">function validate(req, res, next) {
  if (!req.body.name) {
    return res.status(400).send("Name is required");
  }
  next();
}

app.post("/user", validate, (req, res) =&gt; {
  res.send("User created");
});
</code></pre>
<p>✔ Ensures clean and valid input</p>
<hr />
<h2>Key Takeaways</h2>
<ul>
<li><p>Middleware = <strong>functions between request and response</strong></p>
</li>
<li><p>They run <strong>sequentially</strong></p>
</li>
<li><p><code>next()</code> controls flow</p>
</li>
<li><p>You can stack multiple middleware</p>
</li>
<li><p>Used for <strong>logging, auth, validation, parsing, etc.</strong></p>
</li>
</ul>
<hr />
<h2>Final Analogy</h2>
<p>Think of middleware like <strong>security checkpoints at an airport</strong>:</p>
<ul>
<li><p>Passport check → Security scan → Boarding gate</p>
</li>
<li><p>Each step verifies something before allowing you forward</p>
</li>
</ul>
<p>Similarly:</p>
<pre><code class="language-plaintext">Request → Middleware checks → Final Response
</code></pre>
<hr />
<h2>Conclusion</h2>
<p>Middleware is the backbone of Express applications. Once you understand how middleware flows and how <code>next()</code> works, you gain fine-grained control over request handling.</p>
<p>Mastering middleware is essential for building <strong>scalable, maintainable backend systems</strong>.</p>
]]></content:encoded></item><item><title><![CDATA[Handling File Uploads in Express with Multer]]></title><description><![CDATA[Handling File Uploads in Express with Multer
When building real-world backend systems, handling file uploads is unavoidable—profile pictures, documents, PDFs, etc. But unlike JSON data, file uploads r]]></description><link>https://blogs.sayantanbal.in/handling-file-uploads-in-express-with-multer</link><guid isPermaLink="true">https://blogs.sayantanbal.in/handling-file-uploads-in-express-with-multer</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 16:18:45 GMT</pubDate><content:encoded><![CDATA[<h2>Handling File Uploads in Express with Multer</h2>
<p>When building real-world backend systems, handling file uploads is unavoidable—profile pictures, documents, PDFs, etc. But unlike JSON data, file uploads require a different handling mechanism. This is where middleware like <strong>Multer</strong> becomes essential.</p>
<hr />
<h2>Why File Uploads Need Middleware</h2>
<p>In a typical Express.js application running on Node.js, request bodies are usually parsed using middleware like <code>express.json()</code> or <code>express.urlencoded()</code>.</p>
<p>However, file uploads are sent using a special encoding type:</p>
<h3>👉 <code>multipart/form-data</code></h3>
<p>This format:</p>
<ul>
<li><p>Breaks the request body into <strong>multiple parts</strong></p>
</li>
<li><p>Each part can contain <strong>text fields or files</strong></p>
</li>
<li><p>Cannot be parsed by default Express body parsers</p>
</li>
</ul>
<p>So without middleware, Express simply <strong>cannot read file data</strong>.</p>
<hr />
<h2>What is Multer?</h2>
<p>Multer is a middleware specifically designed to handle <code>multipart/form-data</code>.</p>
<p>It:</p>
<ul>
<li><p>Parses incoming file data</p>
</li>
<li><p>Stores files (locally or memory)</p>
</li>
<li><p>Attaches file info to the request object</p>
</li>
</ul>
<p>Think of Multer as a <strong>bridge between raw file data and usable JavaScript objects</strong>.</p>
<hr />
<h2>Understanding the Upload Lifecycle</h2>
<p>Here’s what happens when a file is uploaded:</p>
<ol>
<li><p>Client sends a form with <code>multipart/form-data</code></p>
</li>
<li><p>Request reaches Express</p>
</li>
<li><p>Multer intercepts the request</p>
</li>
<li><p>File is processed and stored</p>
</li>
<li><p>File metadata is attached to:</p>
<ul>
<li><p><code>req.file</code> (single file)</p>
</li>
<li><p><code>req.files</code> (multiple files)</p>
</li>
</ul>
</li>
<li><p>Your route handler uses this data</p>
</li>
</ol>
<hr />
<h2>Installing Multer</h2>
<pre><code class="language-bash">npm install multer
</code></pre>
<hr />
<h2>Basic Setup</h2>
<pre><code class="language-js">const express = require("express");
const multer = require("multer");

const app = express();
</code></pre>
<hr />
<h2>Storage Configuration (Basic)</h2>
<p>By default, Multer stores files in memory. But usually, you want local storage.</p>
<pre><code class="language-js">const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "uploads/");
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + "-" + file.originalname);
  }
});

const upload = multer({ storage });
</code></pre>
<h3>Key Concepts:</h3>
<ul>
<li><p><strong>destination</strong> → where file is stored</p>
</li>
<li><p><strong>filename</strong> → how file is named</p>
</li>
</ul>
<hr />
<h2>Handling Single File Upload</h2>
<pre><code class="language-js">app.post("/upload", upload.single("profile"), (req, res) =&gt; {
  console.log(req.file);
  res.send("File uploaded successfully");
});
</code></pre>
<h3>Important:</h3>
<ul>
<li><p><code>"profile"</code> must match the form input name</p>
</li>
<li><p>File info is available in <code>req.file</code></p>
</li>
</ul>
<hr />
<h2>Handling Multiple File Uploads</h2>
<h3>Option 1: Multiple files with same field</h3>
<pre><code class="language-js">app.post("/upload-multiple", upload.array("photos", 5), (req, res) =&gt; {
  console.log(req.files);
  res.send("Multiple files uploaded");
});
</code></pre>
<ul>
<li><p><code>"photos"</code> → field name</p>
</li>
<li><p><code>5</code> → max number of files</p>
</li>
</ul>
<hr />
<h3>Option 2: Different fields</h3>
<pre><code class="language-js">app.post("/upload-fields", upload.fields([
  { name: "avatar", maxCount: 1 },
  { name: "documents", maxCount: 3 }
]), (req, res) =&gt; {
  console.log(req.files);
  res.send("Files uploaded");
});
</code></pre>
<hr />
<h2>Serving Uploaded Files</h2>
<p>Once files are stored locally, you need to serve them.</p>
<pre><code class="language-js">app.use("/uploads", express.static("uploads"));
</code></pre>
<p>Now files are accessible via:</p>
<pre><code class="language-plaintext">http://localhost:3000/uploads/filename.jpg
</code></pre>
<hr />
<h2>Example HTML Form</h2>
<pre><code class="language-html">&lt;form action="/upload" method="POST" enctype="multipart/form-data"&gt;
  &lt;input type="file" name="profile" /&gt;
  &lt;button type="submit"&gt;Upload&lt;/button&gt;
&lt;/form&gt;
</code></pre>
<h3>Key Point:</h3>
<ul>
<li><code>enctype="multipart/form-data"</code> is <strong>mandatory</strong></li>
</ul>
<hr />
<h2>Common Mistakes to Avoid</h2>
<ul>
<li><p>❌ Forgetting <code>enctype="multipart/form-data"</code></p>
</li>
<li><p>❌ Mismatched field name between form and Multer</p>
</li>
<li><p>❌ Not creating the <code>uploads/</code> directory</p>
</li>
<li><p>❌ Trying to use <code>express.json()</code> for file uploads</p>
</li>
</ul>
<hr />
<h2>Minimal Mental Model</h2>
<ul>
<li><p>Express alone → handles JSON/text</p>
</li>
<li><p>Multer → handles files</p>
</li>
<li><p>multipart/form-data → required format</p>
</li>
</ul>
<hr />
<h2>When to Use Multer</h2>
<p>Use Multer when:</p>
<ul>
<li><p>Uploading profile images</p>
</li>
<li><p>Uploading documents (PDF, resumes)</p>
</li>
<li><p>Handling media files</p>
</li>
</ul>
<p>Avoid overcomplicating early:</p>
<ul>
<li><p>Don’t jump to cloud storage yet (S3, Cloudinary)</p>
</li>
<li><p>First master <strong>local uploads + serving</strong></p>
</li>
</ul>
<hr />
]]></content:encoded></item><item><title><![CDATA[What is Node.js? JavaScript on the Server Explained]]></title><description><![CDATA[📌 Why Do We Even Need Node.js?
Before Node.js existed, JavaScript had one job — run inside browsers.
When you opened a website:

HTML → structure

CSS → styling

JavaScript → interactivity


But all ]]></description><link>https://blogs.sayantanbal.in/what-is-node-js-javascript-on-the-server-explained</link><guid isPermaLink="true">https://blogs.sayantanbal.in/what-is-node-js-javascript-on-the-server-explained</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 16:17:32 GMT</pubDate><content:encoded><![CDATA[<h3>📌 Why Do We Even Need Node.js?</h3>
<p>Before Node.js existed, <strong>JavaScript had one job — run inside browsers</strong>.</p>
<p>When you opened a website:</p>
<ul>
<li><p>HTML → structure</p>
</li>
<li><p>CSS → styling</p>
</li>
<li><p>JavaScript → interactivity</p>
</li>
</ul>
<p>But <strong>all of this happened only in the browser</strong>. JavaScript had <strong>no access to the server</strong>, filesystem, or backend logic.</p>
<p>👉 If you wanted backend logic, you had to use languages like:</p>
<ul>
<li><p>PHP</p>
</li>
<li><p>Java</p>
</li>
<li><p>Python</p>
</li>
</ul>
<p>So developers were forced to use:</p>
<blockquote>
<p>JavaScript for frontend + another language for backend</p>
</blockquote>
<p>That split created complexity.</p>
<hr />
<h2>🧠 What is Node.js?</h2>
<p><strong>Node.js is a JavaScript runtime that allows you to run JavaScript outside the browser — on the server.</strong></p>
<p>In simple terms:</p>
<blockquote>
<p>Node.js lets you build backend systems using JavaScript.</p>
</blockquote>
<hr />
<h2>🧩 JavaScript: Language vs Runtime</h2>
<p>This is where many beginners get confused.</p>
<ul>
<li><p><strong>JavaScript = Programming Language</strong></p>
</li>
<li><p><strong>Node.js = Runtime Environment</strong></p>
</li>
</ul>
<h3>Analogy:</h3>
<p>Think of JavaScript as:</p>
<blockquote>
<p>🧠 A brain that knows how to think</p>
</blockquote>
<p>And Node.js as:</p>
<blockquote>
<p>🏠 A place where that brain can work outside the browser</p>
</blockquote>
<hr />
<h2>🌐 Browser JS vs Server JS</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Browser JavaScript</th>
<th>Node.js (Server)</th>
</tr>
</thead>
<tbody><tr>
<td>Runs in</td>
<td>Browser</td>
<td>Server</td>
</tr>
<tr>
<td>Access to DOM</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Access to files</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Backend logic</td>
<td>No</td>
<td>Yes</td>
</tr>
</tbody></table>
<p>👉 Same language, different environment.</p>
<hr />
<h2>⚙️ How Node.js Made This Possible</h2>
<p>Node.js uses the <strong>V8 Engine</strong> (the same engine used by Chrome).</p>
<h3>🔍 V8 Engine (High-Level Overview)</h3>
<ul>
<li><p>Converts JavaScript into machine code</p>
</li>
<li><p>Executes it very fast</p>
</li>
<li><p>Written in C++</p>
</li>
</ul>
<p>👉 Node.js took this engine and said:</p>
<blockquote>
<p>“Let’s run JavaScript outside the browser.”</p>
</blockquote>
<p>And added:</p>
<ul>
<li><p>File system access</p>
</li>
<li><p>Network handling</p>
</li>
<li><p>OS-level capabilities</p>
</li>
</ul>
<hr />
<h2>🔄 Event-Driven Architecture (Core Idea)</h2>
<p>Node.js works differently from traditional servers.</p>
<h3>Traditional Servers (PHP, Java)</h3>
<ul>
<li><p>Create a <strong>new thread per request</strong></p>
</li>
<li><p>Can become heavy under high traffic</p>
</li>
</ul>
<h3>Node.js Approach</h3>
<ul>
<li><p>Single thread</p>
</li>
<li><p>Uses <strong>event loop + non-blocking I/O</strong></p>
</li>
</ul>
<h3>Analogy:</h3>
<p>Imagine a waiter in a restaurant:</p>
<ul>
<li><p>Traditional system → One waiter per table</p>
</li>
<li><p>Node.js → One smart waiter handling all tables efficiently</p>
</li>
</ul>
<p>👉 Instead of waiting for one task to finish, Node.js:</p>
<ul>
<li><p>Starts a task</p>
</li>
<li><p>Moves to the next</p>
</li>
<li><p>Comes back when the first task is done</p>
</li>
</ul>
<p>This is called:</p>
<blockquote>
<p><strong>Non-blocking, event-driven execution</strong></p>
</blockquote>
<hr />
<h2>⚔️ Node.js vs Traditional Backend Runtimes</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Node.js</th>
<th>PHP / Java</th>
</tr>
</thead>
<tbody><tr>
<td>Language</td>
<td>JavaScript</td>
<td>Different languages</td>
</tr>
<tr>
<td>Thread model</td>
<td>Single-threaded</td>
<td>Multi-threaded</td>
</tr>
<tr>
<td>Performance</td>
<td>Excellent for I/O tasks</td>
<td>Good for CPU-heavy apps</td>
</tr>
<tr>
<td>Learning curve</td>
<td>Easier (one language)</td>
<td>Higher</td>
</tr>
</tbody></table>
<p>👉 Biggest advantage:</p>
<blockquote>
<p>You can use <strong>JavaScript everywhere (frontend + backend)</strong></p>
</blockquote>
<hr />
<h2>🌍 Real-World Use Cases of Node.js</h2>
<p>Node.js is widely used in production systems:</p>
<h3>🔹 APIs &amp; Backend Services</h3>
<ul>
<li><p>REST APIs</p>
</li>
<li><p>GraphQL servers</p>
</li>
</ul>
<h3>🔹 Real-Time Applications</h3>
<ul>
<li><p>Chat apps (like WhatsApp Web)</p>
</li>
<li><p>Live collaboration tools</p>
</li>
</ul>
<h3>🔹 Streaming Applications</h3>
<ul>
<li><p>Video streaming platforms</p>
</li>
<li><p>Music apps</p>
</li>
</ul>
<h3>🔹 Microservices</h3>
<ul>
<li>Scalable backend systems</li>
</ul>
<h3>🔹 Developer Tools</h3>
<ul>
<li><p>Build tools (Webpack, Vite)</p>
</li>
<li><p>CLI tools</p>
</li>
</ul>
<hr />
<h2>🤔 Why Developers Adopted Node.js</h2>
<p>Node.js became popular because:</p>
<h3>✅ Single Language Stack</h3>
<p>No need to switch between JS and another backend language.</p>
<h3>⚡ High Performance for I/O</h3>
<p>Handles thousands of requests efficiently.</p>
<h3>🔄 Asynchronous Nature</h3>
<p>Perfect for modern web apps.</p>
<h3>🌱 Massive Ecosystem</h3>
<ul>
<li><p>npm (Node Package Manager)</p>
</li>
<li><p>Millions of libraries</p>
</li>
</ul>
<hr />
<h2>🧠 Final Takeaway</h2>
<p>Node.js didn’t create a new language.</p>
<p>It simply changed where JavaScript can run.</p>
<blockquote>
<p>From being “just a browser language” 👉 to becoming a <strong>full-stack powerhouse</strong></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[JWT Authentication in Node.js Explained Simply]]></title><description><![CDATA[Why Authentication is Required
Before diving into JWT, let’s understand the core problem.
When a user interacts with your application (login, profile, payments), your server needs to answer:
👉 “Who i]]></description><link>https://blogs.sayantanbal.in/jwt-authentication-in-node-js-explained-simply</link><guid isPermaLink="true">https://blogs.sayantanbal.in/jwt-authentication-in-node-js-explained-simply</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 16:13:25 GMT</pubDate><content:encoded><![CDATA[<h2>Why Authentication is Required</h2>
<p>Before diving into JWT, let’s understand the core problem.</p>
<p>When a user interacts with your application (login, profile, payments), your server needs to answer:</p>
<p>👉 <strong>“Who is this user?”</strong></p>
<p>Without authentication:</p>
<ul>
<li><p>Anyone can access protected data</p>
</li>
<li><p>No user-specific experience</p>
</li>
<li><p>Security risks increase drastically</p>
</li>
</ul>
<p>Authentication ensures:</p>
<ul>
<li><p>Only valid users can access resources</p>
</li>
<li><p>Actions are tied to identities</p>
</li>
<li><p>Sensitive data remains protected</p>
</li>
</ul>
<hr />
<h2>What is Authentication?</h2>
<p>Authentication is the process of verifying <strong>who a user is</strong>.</p>
<p>Example:</p>
<ul>
<li><p>You log in using email &amp; password</p>
</li>
<li><p>Server checks credentials</p>
</li>
<li><p>If valid → user is authenticated</p>
</li>
</ul>
<hr />
<h2>What is JWT?</h2>
<p><strong>JWT (JSON Web Token)</strong> is a compact, secure way to transmit user identity between client and server.</p>
<p>👉 Instead of storing session data on the server, JWT allows <strong>stateless authentication</strong>.</p>
<h3>Stateless Authentication (Simple Explanation)</h3>
<ul>
<li><p>Server does <strong>not store user session</strong></p>
</li>
<li><p>All required user info is stored inside the token</p>
</li>
<li><p>Every request carries that token</p>
</li>
</ul>
<p>This makes systems:</p>
<ul>
<li><p>Scalable</p>
</li>
<li><p>Faster (no DB lookup for session)</p>
</li>
<li><p>Ideal for APIs</p>
</li>
</ul>
<hr />
<h2>Structure of a JWT</h2>
<p>A JWT consists of <strong>3 parts</strong>, separated by dots:</p>
<pre><code class="language-plaintext">xxxxx.yyyyy.zzzzz
</code></pre>
<hr />
<h3>1. Header</h3>
<img src="https://images.openai.com/static-rsc-4/_mL-_v-A3HQQg9M6umti1l6LcLJFWzZc4jfhpSkVpzMNp_ZFMO0lYqT0M6FXMMmmj0BX-g3wsKRTx9w4OVUovb_pb1SVhWMm5nhzdCYs0Tf2fG8M6-4_1X0Qj2yJ_yq4O8e4ZKtpMT0p14QrQwiIy3QaPXtRx9Xsz7NMSetECYzxafJNwFjpoeIG13v2HNHu?purpose=fullsize" alt="Image" style="display:block;margin:0 auto" />

<img src="https://images.openai.com/static-rsc-4/GUP8Ll64llDlR7C9gOqJkHLsv9L6A7kwB3IW1Xmz1wwKRjyMn9aqyjD4AJSePtS0uGk7l6XIBu_Ki8un0OoPWYjGhJJhk4RrKYZ98tsaHt1izfonUpCRpltjR60ljSy2SdFMFrPgbPEMnjbiXc_h6a_GccBX7l1YyrU3VpNc1GZBcU48DT06zuoPaxYbMM8S?purpose=fullsize" alt="Image" style="display:block;margin:0 auto" />

<p>The header contains metadata about the token.</p>
<p>Example:</p>
<pre><code class="language-json">{
  "alg": "HS256",
  "typ": "JWT"
}
</code></pre>
<ul>
<li><p><code>alg</code> → algorithm used for signing</p>
</li>
<li><p><code>typ</code> → token type</p>
</li>
</ul>
<hr />
<h3>2. Payload</h3>
<img src="https://images.openai.com/static-rsc-4/SdC8wFN4sG7F-iYhtiJtSwkjKAUAPznlYL3xecmRgOr6PR9dRsz8fmpE6ZocXrtgcY025VMzFhHskhAXyt_vVwCqehJiV63r4vc9eKlhkIpRabonXTFxPAHCNaejv2ZUYIoUBuTcbcYCeW5xIgQTRH2MiED8Q7prLYcF1JHwW2doaHOxCU6cq9eWdmBmeKVL?purpose=fullsize" alt="Image" style="display:block;margin:0 auto" />

<p>This contains the actual data (called <strong>claims</strong>).</p>
<p>Example:</p>
<pre><code class="language-json">{
  "userId": "12345",
  "email": "user@example.com"
}
</code></pre>
<p>Types of claims:</p>
<ul>
<li><p><strong>Registered</strong> → <code>exp</code>, <code>iat</code></p>
</li>
<li><p><strong>Public</strong> → custom data</p>
</li>
<li><p><strong>Private</strong> → app-specific</p>
</li>
</ul>
<p>⚠️ Important: Payload is <strong>not encrypted</strong>, only encoded.</p>
<hr />
<h3>3. Signature</h3>
<img src="https://images.openai.com/static-rsc-4/djqk8001V-dEZKPRx99DY0j1l19vr8zOvNmfcNriBcsCnPayGYRexf714bNQANxf9SJFJAxAb6P4YVh8Vabl3hZWm3JfMpfUTIO30s2bdahCyDbUQLSpDd5Qfr_ALLhZZsnhZFw3xS9XNe14nTuarkOaTsr2oEmypT9nLuBTNKqyFwxtVvXzw6hOZ_xqaQnB?purpose=fullsize" alt="Image" style="display:block;margin:0 auto" />

<img src="https://images.openai.com/static-rsc-4/5l-JH2BbK__7zU9_jSG9L0CxyJpKhKB2P7BRy509SFxCcSII6oLMh3qmVWSWI0Sf0FjE5DigQGbx5sWtasHKBUo54fqVYZwkv3n9pHCw2EUijWZGCRZTXCytIvfxtH9_kGAanEBcmx4IRb6Zvuoec5uT4Kpxr9oTWDeMHtSQtE0ebAXuY2C3b8PDd6mHMFeR?purpose=fullsize" alt="Image" style="display:block;margin:0 auto" />

<p>The signature ensures the token is <strong>not tampered with</strong>.</p>
<p>Created using:</p>
<pre><code class="language-plaintext">Header + Payload + Secret Key
</code></pre>
<p>If someone modifies the token → signature becomes invalid.</p>
<hr />
<h2>Login Flow Using JWT</h2>
<img src="https://images.openai.com/static-rsc-4/y9KWo2SDDcKLrADoGfagft-NU1qMIycpEZ1UaOJc_FM6jcq5h5-K8L8tIARB30YrwJeVjMpwe6H6w2jrVe7MrOJI8rsTPmgY9EMxGBdNfw14IljFrYkU0SB18hKRfNgstq2B_vWF2rkUtziY3yTAt3f4LitaND7M4js2xpxTlQdql8oI1HllZ4m6uPeKMivT?purpose=fullsize" alt="Image" style="display:block;margin:0 auto" />

<img src="https://images.openai.com/static-rsc-4/GxLmc_c_y9PaMVCaQYsd2W9xJer2QsQGRnKa4klxawmp3gUBmFb1dLmiS0ZsQU5FPYMZ7LWE9RHAKxiOcpWrWkdXLcEuCDYconvmpqgbtN2Yvt-eS5GydW0rkYUGu2ezqtWDhO3gDKdFqtgVArJVREdAMLRr8Z4R_z1vaZ9eoaS78Vmh9PLA7gFdZYPFzEaU?purpose=fullsize" alt="Image" style="display:block;margin:0 auto" />

<p>Here’s how JWT-based login works:</p>
<ol>
<li><p>User sends login request (email + password)</p>
</li>
<li><p>Server verifies credentials</p>
</li>
<li><p>Server generates JWT</p>
</li>
<li><p>Token is sent back to client</p>
</li>
<li><p>Client stores token (localStorage/cookie)</p>
</li>
</ol>
<hr />
<h2>Sending Token with Requests</h2>
<p>After login, every request must include the token.</p>
<p>Common method:</p>
<pre><code class="language-plaintext">Authorization: Bearer &lt;token&gt;
</code></pre>
<p>Example in fetch:</p>
<pre><code class="language-js">fetch('/profile', {
  headers: {
    Authorization: `Bearer ${token}`
  }
})
</code></pre>
<hr />
<h2>Protecting Routes Using JWT</h2>
<p>On protected routes:</p>
<ol>
<li><p>Server reads token from request header</p>
</li>
<li><p>Verifies token using secret key</p>
</li>
<li><p>Extracts user data</p>
</li>
<li><p>Allows or denies access</p>
</li>
</ol>
<p>Example (Express middleware):</p>
<pre><code class="language-js">const jwt = require('jsonwebtoken');

function authMiddleware(req, res, next) {
  const token = req.headers.authorization?.split(' ')[1];

  if (!token) {
    return res.status(401).send('Access Denied');
  }

  try {
    const decoded = jwt.verify(token, 'SECRET_KEY');
    req.user = decoded;
    next();
  } catch (err) {
    res.status(400).send('Invalid Token');
  }
}
</code></pre>
<hr />
<h2>Key Takeaways</h2>
<ul>
<li><p>Authentication = verifying user identity</p>
</li>
<li><p>JWT enables <strong>stateless authentication</strong></p>
</li>
<li><p>Token has 3 parts: Header, Payload, Signature</p>
</li>
<li><p>No server-side session storage required</p>
</li>
<li><p>Token must be sent with every request</p>
</li>
<li><p>Middleware protects routes</p>
</li>
</ul>
<hr />
<h2>Final Insight</h2>
<p>JWT is powerful, but use it correctly:</p>
<ul>
<li><p>Always set expiration (<code>exp</code>)</p>
</li>
<li><p>Never store sensitive data in payload</p>
</li>
<li><p>Keep your secret key secure</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Creating Routes and Handling Requests with Express]]></title><description><![CDATA[When you start building backend applications with Node.js, you’ll quickly realize that handling routes, requests, and responses manually can become repetitive and messy.
That’s where Express.js comes ]]></description><link>https://blogs.sayantanbal.in/creating-routes-and-handling-requests-with-express</link><guid isPermaLink="true">https://blogs.sayantanbal.in/creating-routes-and-handling-requests-with-express</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 16:08:09 GMT</pubDate><content:encoded><![CDATA[<p>When you start building backend applications with Node.js, you’ll quickly realize that handling routes, requests, and responses manually can become repetitive and messy.</p>
<p>That’s where <strong>Express.js</strong> comes in.</p>
<hr />
<h2>📌 What is Express.js?</h2>
<p><strong>Express.js</strong> is a minimal and flexible web framework for Node.js that provides a structured way to build web applications and APIs.</p>
<p>Instead of writing everything from scratch using Node’s core modules, Express gives you:</p>
<ul>
<li><p>Clean routing</p>
</li>
<li><p>Middleware support</p>
</li>
<li><p>Simplified request/response handling</p>
</li>
</ul>
<hr />
<h2>🤔 Why Express Simplifies Node.js Development</h2>
<p>Using the built-in <code>http</code> module in Node.js is powerful—but verbose.</p>
<h3>🔴 Raw Node.js Example</h3>
<pre><code class="language-js">const http = require("http");

const server = http.createServer((req, res) =&gt; {
  if (req.url === "/" &amp;&amp; req.method === "GET") {
    res.end("Hello World");
  }
});

server.listen(3000);
</code></pre>
<p>Problems:</p>
<ul>
<li><p>Manual routing logic</p>
</li>
<li><p>Hard to scale</p>
</li>
<li><p>Poor readability</p>
</li>
</ul>
<hr />
<h3>🟢 Express.js Equivalent</h3>
<pre><code class="language-js">const express = require("express");
const app = express();

app.get("/", (req, res) =&gt; {
  res.send("Hello World");
});

app.listen(3000);
</code></pre>
<p>Much cleaner, right?</p>
<p>👉 Express abstracts away boilerplate so you can focus on logic instead of plumbing.</p>
<hr />
<h2>⚙️ Creating Your First Express Server</h2>
<h3>Step 1: Install Express</h3>
<pre><code class="language-bash">npm init -y
npm install express
</code></pre>
<hr />
<h3>Step 2: Create Server</h3>
<pre><code class="language-js">const express = require("express");
const app = express();

app.listen(3000, () =&gt; {
  console.log("Server running on port 3000");
});
</code></pre>
<hr />
<h2>🌐 Handling GET Requests</h2>
<p>GET requests are used to <strong>fetch data</strong>.</p>
<pre><code class="language-js">app.get("/", (req, res) =&gt; {
  res.send("Welcome to my server");
});
</code></pre>
<p>You can also use route paths:</p>
<pre><code class="language-js">app.get("/about", (req, res) =&gt; {
  res.send("About Page");
});
</code></pre>
<hr />
<h2>📦 Handling POST Requests</h2>
<p>POST requests are used to <strong>send data to the server</strong>.</p>
<p>First, enable JSON parsing middleware:</p>
<pre><code class="language-js">app.use(express.json());
</code></pre>
<p>Now handle POST:</p>
<pre><code class="language-js">app.post("/data", (req, res) =&gt; {
  const userData = req.body;
  res.send(`Received: ${JSON.stringify(userData)}`);
});
</code></pre>
<hr />
<h2>📤 Sending Responses</h2>
<p>Express provides multiple response methods:</p>
<pre><code class="language-js">res.send("Text response");
res.json({ message: "JSON response" });
res.status(200).send("Status set");
</code></pre>
<p>These make response handling far more intuitive compared to raw Node.js.</p>
<hr />
<h2>🧭 Understanding Routing (Core Concept)</h2>
<p>Routing means defining how your server responds to different endpoints.</p>
<pre><code class="language-js">app.get("/user", (req, res) =&gt; {
  res.send("User route");
});

app.post("/user", (req, res) =&gt; {
  res.send("Create user");
});
</code></pre>
<p>👉 Same route, different methods → different behavior.</p>
<hr />
<h2>🧠 Key Takeaways</h2>
<ul>
<li><p>Express.js is a <strong>lightweight abstraction over Node.js</strong></p>
</li>
<li><p>It simplifies:</p>
<ul>
<li><p>Routing</p>
</li>
<li><p>Request handling</p>
</li>
<li><p>Response formatting</p>
</li>
</ul>
</li>
<li><p>Makes your backend:</p>
<ul>
<li><p>Cleaner</p>
</li>
<li><p>Scalable</p>
</li>
<li><p>Easier to maintain</p>
</li>
</ul>
</li>
</ul>
<hr />
<h2>🔚 Final Thoughts</h2>
<p>If you're serious about backend development, learning <strong>Express.js</strong> is non-negotiable. It’s the foundation for building APIs, full-stack apps, and scalable systems in Node.js.</p>
<p>Once you're comfortable with this, the next step is:</p>
<ul>
<li><p>Middleware</p>
</li>
<li><p>Routing architecture</p>
</li>
<li><p>REST API design</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Setting Up Your First Node.js Application Step-by-Step]]></title><description><![CDATA[Getting started with Node.js is the first step toward building backend systems, APIs, and full-stack applications using JavaScript. This guide walks you through the complete setup process—from install]]></description><link>https://blogs.sayantanbal.in/setting-up-your-first-node-js-application-step-by-step</link><guid isPermaLink="true">https://blogs.sayantanbal.in/setting-up-your-first-node-js-application-step-by-step</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 16:04:52 GMT</pubDate><content:encoded><![CDATA[<p>Getting started with Node.js is the first step toward building backend systems, APIs, and full-stack applications using JavaScript. This guide walks you through the complete setup process—from installation to running your first server—without using any frameworks.</p>
<hr />
<h2>1. Installing Node.js</h2>
<p>Node.js is a JavaScript runtime that allows you to execute JavaScript outside the browser.</p>
<h3>Steps:</h3>
<ol>
<li><p>Go to the official Node.js website: <a href="https://nodejs.org">https://nodejs.org</a></p>
</li>
<li><p>Download the <strong>LTS (Long-Term Support)</strong> version</p>
</li>
<li><p>Install it using the default settings</p>
</li>
</ol>
<p>This installation also includes <strong>npm (Node Package Manager)</strong>, which you’ll use later for managing dependencies.</p>
<hr />
<h2>2. Verifying Installation</h2>
<p>Once installed, you need to confirm that Node.js is correctly set up.</p>
<p>Open your terminal (or command prompt) and run:</p>
<pre><code class="language-bash">node -v
</code></pre>
<p>You should see a version number like:</p>
<pre><code class="language-bash">v24.x.x
</code></pre>
<p>Now check npm:</p>
<pre><code class="language-bash">npm -v
</code></pre>
<p>If both commands return versions, your setup is successful.</p>
<p>💡 <strong>Tip:</strong> If you ever forget common commands or want quick one-liner solutions for JavaScript/Node tasks, platforms like Practica JS can be very handy for fast reference and practice.</p>
<hr />
<h2>3. Understanding Node REPL</h2>
<p>REPL stands for:</p>
<blockquote>
<p><strong>Read – Evaluate – Print – Loop</strong></p>
</blockquote>
<p>It’s an interactive environment where you can execute JavaScript code line-by-line.</p>
<h3>Start REPL:</h3>
<pre><code class="language-bash">node
</code></pre>
<p>You’ll see something like:</p>
<pre><code class="language-bash">&gt;
</code></pre>
<h3>Try this:</h3>
<pre><code class="language-js">console.log("Hello from REPL");
</code></pre>
<p>Output:</p>
<pre><code class="language-bash">Hello from REPL
</code></pre>
<h3>Exit REPL:</h3>
<pre><code class="language-bash">.exit
</code></pre>
<p>or press:</p>
<pre><code class="language-bash">Ctrl + C (twice)
</code></pre>
<h3>Why REPL matters:</h3>
<ul>
<li><p>Quick testing of JavaScript code</p>
</li>
<li><p>Debugging logic</p>
</li>
<li><p>Learning Node interactively</p>
</li>
</ul>
<hr />
<h2>4. Creating Your First JavaScript File</h2>
<p>Now let’s move from interactive mode to writing actual scripts.</p>
<h3>Step 1: Create a file</h3>
<p>Create a file named:</p>
<pre><code class="language-bash">app.js
</code></pre>
<h3>Step 2: Add code</h3>
<pre><code class="language-js">console.log("Hello, Node.js!");
</code></pre>
<hr />
<h2>5. Running Your Script</h2>
<p>To execute the file, navigate to its directory in terminal and run:</p>
<pre><code class="language-bash">node app.js
</code></pre>
<h3>Output:</h3>
<pre><code class="language-bash">Hello, Node.js!
</code></pre>
<p>This is your first Node.js execution 🎉</p>
<hr />
<h2>6. Writing Your First “Hello World” Server</h2>
<p>Now let’s create a basic HTTP server using Node’s built-in module (no frameworks).</p>
<h3>Step 1: Update <code>app.js</code></h3>
<pre><code class="language-js">const http = require("http");

const server = http.createServer((req, res) =&gt; {
  res.write("Hello World from Node.js Server");
  res.end();
});

server.listen(3000, () =&gt; {
  console.log("Server running at http://localhost:3000/");
});
</code></pre>
<hr />
<h3>Step 2: Run the server</h3>
<pre><code class="language-bash">node app.js
</code></pre>
<h3>Step 3: Open browser</h3>
<p>Go to:</p>
<pre><code class="language-bash">http://localhost:3000
</code></pre>
<h3>Output:</h3>
<pre><code class="language-bash">Hello World from Node.js Server
</code></pre>
<hr />
<h2>What’s Happening Behind the Scenes?</h2>
<ul>
<li><p><code>require("http")</code> → imports Node’s built-in HTTP module</p>
</li>
<li><p><code>createServer()</code> → creates a server instance</p>
</li>
<li><p><code>req</code> → incoming request object</p>
</li>
<li><p><code>res</code> → response object sent back to client</p>
</li>
<li><p><code>listen(3000)</code> → server starts listening on port 3000</p>
</li>
</ul>
<hr />
<h2>Key Takeaways</h2>
<ul>
<li><p>Node.js allows you to run JavaScript outside the browser</p>
</li>
<li><p>REPL is useful for quick experimentation</p>
</li>
<li><p>Scripts are executed using the <code>node</code> command</p>
</li>
<li><p>You can create a basic server without any frameworks</p>
</li>
<li><p>Node’s core modules (like <code>http</code>) are powerful enough for fundamentals</p>
</li>
</ul>
<hr />
<h2>What’s Next?</h2>
<p>Once you’re comfortable with this setup, you can move on to:</p>
<ul>
<li><p>File system operations (<code>fs</code> module)</p>
</li>
<li><p>Handling routes manually</p>
</li>
<li><p>Understanding asynchronous behavior in Node.js</p>
</li>
</ul>
<hr />
<p>If you want, I can also:</p>
<ul>
<li><p>Add <strong>SEO title + meta description</strong></p>
</li>
<li><p>Suggest <strong>Hashnode tags</strong></p>
</li>
<li><p>Create a <strong>cover image prompt</strong></p>
</li>
<li><p>Or help you make this stand out from others in your cohort</p>
</li>
</ul>
<p>Just tell me 👍</p>
]]></content:encoded></item><item><title><![CDATA[URL Parameters vs Query Strings in Express.js]]></title><description><![CDATA[When building APIs with Express.js, understanding how data flows through URLs is fundamental. Two of the most common ways to pass data in a request URL are URL parameters (route params) and query stri]]></description><link>https://blogs.sayantanbal.in/url-parameters-vs-query-strings-in-express-js</link><guid isPermaLink="true">https://blogs.sayantanbal.in/url-parameters-vs-query-strings-in-express-js</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 15:47:39 GMT</pubDate><content:encoded><![CDATA[<p>When building APIs with Express.js, understanding how data flows through URLs is fundamental. Two of the most common ways to pass data in a request URL are <strong>URL parameters (route params)</strong> and <strong>query strings</strong>.</p>
<p>They may look similar at first glance, but they serve very different purposes in API design.</p>
<hr />
<h2>🔹 What Are URL Parameters?</h2>
<p>URL parameters (also called <strong>route parameters</strong>) are dynamic values embedded directly in the URL path.</p>
<p>They are typically used to <strong>identify a specific resource</strong>.</p>
<h3>Example:</h3>
<pre><code class="language-plaintext">/users/123
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>123</code> is a <strong>URL parameter</strong></p>
</li>
<li><p>It represents a <strong>specific user ID</strong></p>
</li>
</ul>
<h3>Express Example:</h3>
<pre><code class="language-js">app.get('/users/:id', (req, res) =&gt; {
  const userId = req.params.id;
  res.send(`User ID is ${userId}`);
});
</code></pre>
<h3>Key Characteristics:</h3>
<ul>
<li><p>Part of the URL path</p>
</li>
<li><p>Used as <strong>identifiers</strong></p>
</li>
<li><p>Required to match the route</p>
</li>
<li><p>Clean and RESTful</p>
</li>
</ul>
<hr />
<h2>🔹 What Are Query Parameters?</h2>
<p>Query parameters are key-value pairs appended to the end of a URL after a <code>?</code>.</p>
<p>They are used to <strong>modify or filter data</strong>, not identify it.</p>
<h3>Example:</h3>
<pre><code class="language-plaintext">/users?age=25&amp;city=Kolkata
</code></pre>
<p>Here:</p>
<ul>
<li><p><code>age=25</code> and <code>city=Kolkata</code> are <strong>query parameters</strong></p>
</li>
<li><p>They act as <strong>filters</strong></p>
</li>
</ul>
<h3>Express Example:</h3>
<pre><code class="language-js">app.get('/users', (req, res) =&gt; {
  const age = req.query.age;
  const city = req.query.city;

  res.send(`Filtering users by age \({age} and city \){city}`);
});
</code></pre>
<h3>Key Characteristics:</h3>
<ul>
<li><p>Appear after <code>?</code> in the URL</p>
</li>
<li><p>Used as <strong>filters, sorting, or modifiers</strong></p>
</li>
<li><p>Optional by nature</p>
</li>
<li><p>Can have multiple values</p>
</li>
</ul>
<p>Mind map -</p>
<img src="https://cdn.hashnode.com/uploads/covers/69517129b3f42beb72514f64/b326bf9d-5238-4b40-8bf4-10557b063269.png" alt="" style="display:block;margin:0 auto" />

<hr />
<h2>🔹 Core Difference: Params vs Query</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>URL Parameters</th>
<th>Query Parameters</th>
</tr>
</thead>
<tbody><tr>
<td>Purpose</td>
<td>Identify a resource</td>
<td>Filter or modify results</td>
</tr>
<tr>
<td>Location</td>
<td>Inside URL path</td>
<td>After <code>?</code></td>
</tr>
<tr>
<td>Example</td>
<td><code>/users/123</code></td>
<td><code>/users?age=25</code></td>
</tr>
<tr>
<td>Express Access</td>
<td><code>req.params</code></td>
<td><code>req.query</code></td>
</tr>
<tr>
<td>Nature</td>
<td>Required</td>
<td>Optional</td>
</tr>
</tbody></table>
<hr />
<h3>Mind map -</h3>
<img src="https://cdn.hashnode.com/uploads/covers/69517129b3f42beb72514f64/03386d8d-8f7c-4431-80ae-a805493a15f4.png" alt="" style="display:block;margin:0 auto" />

<h2>🔹 Practical Examples</h2>
<h3>1. User Profile (Identifier → Params)</h3>
<pre><code class="language-plaintext">GET /users/123
</code></pre>
<pre><code class="language-js">app.get('/users/:id', (req, res) =&gt; {
  const id = req.params.id;
  res.send(`Fetching user with ID ${id}`);
});
</code></pre>
<p>✔ Use params because you're targeting <strong>one specific user</strong></p>
<hr />
<h3>2. Search or Filtering (Modifier → Query)</h3>
<pre><code class="language-plaintext">GET /users?age=25&amp;city=Kolkata
</code></pre>
<pre><code class="language-js">app.get('/users', (req, res) =&gt; {
  const { age, city } = req.query;
  res.send(`Filtering users with age \({age} in \){city}`);
});
</code></pre>
<p>✔ Use query because you're <strong>refining results</strong></p>
<hr />
<h3>3. Combining Both</h3>
<p>You can use both together:</p>
<pre><code class="language-plaintext">GET /users/123/posts?sort=latest
</code></pre>
<pre><code class="language-js">app.get('/users/:id/posts', (req, res) =&gt; {
  const userId = req.params.id;
  const sort = req.query.sort;

  res.send(`Posts of user \({userId}, sorted by \){sort}`);
});
</code></pre>
<hr />
<h2>🔹 When to Use Params vs Query</h2>
<h3>Use URL Parameters when:</h3>
<ul>
<li><p>You are accessing a <strong>specific resource</strong></p>
</li>
<li><p>The value is <strong>mandatory</strong></p>
</li>
<li><p>It represents an <strong>identity</strong></p>
</li>
</ul>
<p>✔ Examples:</p>
<ul>
<li><p><code>/products/456</code></p>
</li>
<li><p><code>/orders/789</code></p>
</li>
</ul>
<hr />
<h3>Use Query Parameters when:</h3>
<ul>
<li><p>You are <strong>filtering, sorting, or paginating</strong></p>
</li>
<li><p>The values are <strong>optional</strong></p>
</li>
<li><p>You want flexible API behavior</p>
</li>
</ul>
<p>✔ Examples:</p>
<ul>
<li><p><code>/products?category=electronics</code></p>
</li>
<li><p><code>/orders?status=delivered&amp;page=2</code></p>
</li>
</ul>
<hr />
<h2>🔹 Best Practices</h2>
<ul>
<li><p>Treat <strong>params as identifiers</strong>, not filters</p>
</li>
<li><p>Keep URLs <strong>clean and meaningful</strong></p>
</li>
<li><p>Avoid mixing responsibilities (don’t use query for IDs)</p>
</li>
<li><p>Use query params for:</p>
<ul>
<li><p>Pagination (<code>page=1</code>)</p>
</li>
<li><p>Sorting (<code>sort=price</code>)</p>
</li>
<li><p>Filtering (<code>category=books</code>)</p>
</li>
</ul>
</li>
</ul>
<hr />
<h2>🔹 Mental Model (Important)</h2>
<ul>
<li><p><strong>Params = “Which exact thing?”</strong></p>
</li>
<li><p><strong>Query = “How should I view or filter it?”</strong></p>
</li>
</ul>
<hr />
<h2>🔹 Final Takeaway</h2>
<p>If you're designing APIs:</p>
<ul>
<li><p>Think of <strong>URL params as primary keys</strong></p>
</li>
<li><p>Think of <strong>query strings as SQL WHERE clauses</strong></p>
</li>
</ul>
<p>This distinction leads to cleaner, more scalable, and RESTful API design.</p>
<hr />
<p>If you want, I can next help you turn this into a <strong>perfect Hashnode blog with visuals + diagrams + SEO optimization</strong>, or even align it with your cohort grading rubric.</p>
]]></content:encoded></item><item><title><![CDATA[Storing Uploaded Files and Serving Them in Express]]></title><description><![CDATA[When building real-world applications, handling file uploads (images, PDFs, videos, etc.) is a common requirement. But uploading is just one part — storing, serving, and securing those files is equall]]></description><link>https://blogs.sayantanbal.in/storing-uploaded-files-and-serving-them-in-express</link><guid isPermaLink="true">https://blogs.sayantanbal.in/storing-uploaded-files-and-serving-them-in-express</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 15:36:33 GMT</pubDate><content:encoded><![CDATA[<p>When building real-world applications, handling file uploads (images, PDFs, videos, etc.) is a common requirement. But uploading is just one part — <strong>storing, serving, and securing those files</strong> is equally important.</p>
<p>In this guide, we’ll break down how file storage works in Node.js with Express, along with best practices used in production systems.</p>
<h2>📦 Where Uploaded Files Are Stored</h2>
<p>When a user uploads a file, the backend must decide <strong>where to store it</strong>. Broadly, there are two approaches:</p>
<h3>1. Local File System (Server Storage)</h3>
<p>Files are stored directly on the server's disk.</p>
<p>Example structure:</p>
<pre><code class="language-plaintext">project-root/
│
├── uploads/
│   ├── images/
│   │   ├── img1.jpg
│   │   ├── img2.png
│   │
│   ├── documents/
│       ├── file1.pdf
│
├── server.js
</code></pre>
<p><strong>How it works:</strong></p>
<ul>
<li><p>A middleware like <code>multer</code> saves files into a folder (<code>uploads/</code>)</p>
</li>
<li><p>File path is stored in your database</p>
</li>
<li><p>Later, files are served via Express</p>
</li>
</ul>
<h3>2. External Storage (Cloud / Object Storage)</h3>
<p>Instead of storing files locally, you use services like:</p>
<ul>
<li><p>AWS S3</p>
</li>
<li><p>Cloudinary</p>
</li>
<li><p>Firebase Storage</p>
</li>
</ul>
<p><strong>How it works:</strong></p>
<ul>
<li><p>File is uploaded directly (or via backend) to cloud storage</p>
</li>
<li><p>You store the <strong>file URL</strong> in your database</p>
</li>
<li><p>Files are served directly from CDN</p>
</li>
</ul>
<h2>⚖️ Local Storage vs External Storage</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Local Storage</th>
<th>External Storage</th>
</tr>
</thead>
<tbody><tr>
<td>Setup</td>
<td>Simple</td>
<td>Requires configuration</td>
</tr>
<tr>
<td>Scalability</td>
<td>Poor</td>
<td>Highly scalable</td>
</tr>
<tr>
<td>Performance</td>
<td>Limited</td>
<td>CDN optimized</td>
</tr>
<tr>
<td>Cost</td>
<td>Free (initially)</td>
<td>Pay-as-you-scale</td>
</tr>
<tr>
<td>Reliability</td>
<td>Risky (server crash = data loss)</td>
<td>Highly reliable</td>
</tr>
</tbody></table>
<p>👉 <strong>Rule of thumb:</strong></p>
<ul>
<li><p>Use <strong>local storage for small projects / learning</strong></p>
</li>
<li><p>Use <strong>external storage for production apps</strong></p>
</li>
</ul>
<h2>📁 Serving Static Files in Express</h2>
<p>Express provides a built-in middleware to serve static files:</p>
<pre><code class="language-js">const express = require("express");
const path = require("path");

const app = express();

// Serve files from "uploads" folder
app.use("/uploads", express.static(path.join(__dirname, "uploads")));
</code></pre>
<h3>What this does:</h3>
<ul>
<li><p>Maps <code>/uploads</code> URL path to the actual <code>uploads/</code> folder</p>
</li>
<li><p>Makes files publicly accessible</p>
</li>
</ul>
<h2>🌐 Accessing Uploaded Files via URL</h2>
<p>If you have a file stored like:</p>
<pre><code class="language-plaintext">uploads/images/profile.jpg
</code></pre>
<p>You can access it via:</p>
<pre><code class="language-plaintext">http://localhost:3000/uploads/images/profile.jpg
</code></pre>
<p>👉 This works because of:</p>
<pre><code class="language-js">app.use("/uploads", express.static("uploads"));
</code></pre>
<h2>🛠️ Upload Example Using Multer</h2>
<pre><code class="language-js">const multer = require("multer");

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "uploads/images");
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + "-" + file.originalname);
  }
});

const upload = multer({ storage: storage });

app.post("/upload", upload.single("file"), (req, res) =&gt; {
  res.send({
    message: "File uploaded successfully",
    filePath: req.file.path
  });
});
</code></pre>
<h2>🔐 Security Considerations for File Uploads</h2>
<p>This is where most beginners make mistakes. File uploads are a <strong>major attack surface</strong>.</p>
<h3>1. Validate File Type</h3>
<p>Never trust client input.</p>
<pre><code class="language-js">fileFilter: (req, file, cb) =&gt; {
  if (file.mimetype.startsWith("image/")) {
    cb(null, true);
  } else {
    cb(new Error("Only images allowed"), false);
  }
}
</code></pre>
<h3>2. Limit File Size</h3>
<pre><code class="language-js">limits: { fileSize: 5 * 1024 * 1024 } // 5MB
</code></pre>
<h3>3. Avoid Executable Files</h3>
<p>Block <code>.js</code>, <code>.exe</code>, <code>.sh</code>, etc.</p>
<h3>4. Use Unique File Names</h3>
<p>Prevent overwriting:</p>
<pre><code class="language-js">Date.now() + "-" + file.originalname
</code></pre>
<h3>5. Store Outside Public Root (Advanced)</h3>
<p>Instead of directly exposing <code>/uploads</code>, use a controller:</p>
<pre><code class="language-js">app.get("/file/:name", (req, res) =&gt; {
  res.sendFile(path.join(__dirname, "uploads", req.params.name));
});
</code></pre>
<h3>6. Scan Files (Production)</h3>
<p>Use antivirus or scanning tools for:</p>
<ul>
<li><p>PDFs</p>
</li>
<li><p>Documents</p>
</li>
<li><p>User uploads</p>
</li>
</ul>
<h3>Here's a prod grade structure ( it has sharding, careful if following this )</h3>
<img src="https://cdn.hashnode.com/uploads/covers/69517129b3f42beb72514f64/91092f21-7090-417c-b75d-211718732df4.png" alt="" style="display:block;margin:0 auto" />

<h2>📚 Static File Serving Concept (Important)</h2>
<p>Static files are files that:</p>
<ul>
<li><p>Don’t change dynamically</p>
</li>
<li><p>Are served directly to the client</p>
</li>
</ul>
<p>Examples:</p>
<ul>
<li><p>Images</p>
</li>
<li><p>CSS files</p>
</li>
<li><p>PDFs</p>
</li>
</ul>
<p>Express acts like a <strong>file server</strong> when using:</p>
<pre><code class="language-js">express.static()
</code></pre>
<p>👉 Instead of writing routes manually, Express:</p>
<ul>
<li><p>Locates the file</p>
</li>
<li><p>Streams it to the client</p>
</li>
<li><p>Sets correct headers</p>
</li>
</ul>
<p>Here's a prod grade example -</p>
<img src="https://cdn.hashnode.com/uploads/covers/69517129b3f42beb72514f64/69dcc7f2-f1cb-4b9e-8e59-d70c197c83ef.png" alt="" style="display:block;margin:0 auto" />

<h2>🧠 Best Practices Summary</h2>
<ul>
<li><p>Use <code>multer</code> for handling uploads</p>
</li>
<li><p>Separate folders by file type (images, docs, etc.)</p>
</li>
<li><p>Never trust user-uploaded files</p>
</li>
<li><p>Prefer cloud storage in production</p>
</li>
<li><p>Use CDN for faster delivery</p>
</li>
<li><p>Store only file paths/URLs in DB (not actual files)</p>
</li>
</ul>
<h2>🚀 Final Thought</h2>
<p>File handling may look simple, but at scale, it becomes a <strong>system design problem</strong> involving:</p>
<ul>
<li><p>Storage architecture</p>
</li>
<li><p>Security layers</p>
</li>
<li><p>CDN optimization</p>
</li>
<li><p>Cost management</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Sessions vs JWT vs Cookies: Understanding Authentication Approaches]]></title><description><![CDATA[Authentication is a core part of any backend system. Whether you're building a simple web app or a scalable SaaS product, you need a reliable way to verify users.
Three terms come up repeatedly in thi]]></description><link>https://blogs.sayantanbal.in/sessions-vs-jwt-vs-cookies-understanding-authentication-approaches</link><guid isPermaLink="true">https://blogs.sayantanbal.in/sessions-vs-jwt-vs-cookies-understanding-authentication-approaches</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 15:24:53 GMT</pubDate><content:encoded><![CDATA[<p>Authentication is a core part of any backend system. Whether you're building a simple web app or a scalable SaaS product, you need a reliable way to verify users.</p>
<p>Three terms come up repeatedly in this context:</p>
<ul>
<li><p><strong>Sessions</strong></p>
</li>
<li><p><strong>Cookies</strong></p>
</li>
<li><p><strong>JWT (JSON Web Tokens)</strong></p>
</li>
</ul>
<p>They’re often confused or used interchangeably — but they solve different parts of the problem.</p>
<p>Let’s break this down clearly and practically.</p>
<h2>What Are Cookies?</h2>
<p>A <strong>cookie</strong> is a small piece of data stored in the user’s browser.</p>
<ul>
<li><p>Sent <strong>from server → browser</strong></p>
</li>
<li><p>Automatically included in <strong>every request → server</strong></p>
</li>
</ul>
<h3>Example</h3>
<pre><code class="language-javascript">Set-Cookie: sessionId=abc123; HttpOnly
</code></pre>
<h3>Key Points</h3>
<ul>
<li><p>Stored on the <strong>client (browser)</strong></p>
</li>
<li><p>Automatically attached to requests</p>
</li>
<li><p>Can store:</p>
<ul>
<li><p>Session IDs</p>
</li>
<li><p>JWT tokens</p>
</li>
<li><p>Preferences</p>
</li>
</ul>
</li>
</ul>
<p>👉 ❗️Cookies are just a <strong>storage + transport mechanism</strong>, not an authentication strategy by themselves.</p>
<h2>What Are Sessions?</h2>
<p>A <strong>session</strong> is a server-side way to track a user.</p>
<h3>How It Works</h3>
<ol>
<li><p>User logs in</p>
</li>
<li><p>Server creates a session:</p>
<pre><code class="language-javascript">session = {
  userId: "123",
  createdAt: ...
}
</code></pre>
</li>
<li><p>Server stores it (memory / DB / Redis)</p>
</li>
<li><p>Server sends a <strong>session ID via cookie</strong></p>
</li>
<li><p>Browser sends cookie on every request</p>
</li>
<li><p>Server looks up session using that ID</p>
</li>
</ol>
<h3>Key Points</h3>
<ul>
<li><p><strong>Stateful</strong> (server stores user data)</p>
</li>
<li><p>Session ID is usually stored in a cookie</p>
</li>
<li><p>Requires server-side storage</p>
</li>
</ul>
<h2>What Are JWT Tokens?</h2>
<p>A <strong>JWT (JSON Web Token)</strong> is a self-contained token that stores user data.</p>
<h3>Structure</h3>
<pre><code class="language-javascript">header.payload.signature
</code></pre>
<h3>Example Payload</h3>
<pre><code class="language-json">{
  "userId": "123",
  "role": "admin"
}
</code></pre>
<h3>How It Works</h3>
<ol>
<li><p>User logs in</p>
</li>
<li><p>Server generates JWT</p>
</li>
<li><p>Sends it to client</p>
</li>
<li><p>Client stores it (cookie / localStorage)</p>
</li>
<li><p>Client sends token with each request</p>
</li>
<li><p>Server <strong>verifies signature</strong>, no DB lookup needed</p>
</li>
</ol>
<h3>Key Points</h3>
<ul>
<li><p><strong>Stateless</strong></p>
</li>
<li><p>No server-side storage required</p>
</li>
<li><p>Everything is inside the token</p>
</li>
</ul>
<h2>Stateful vs Stateless Authentication</h2>
<table>
<thead>
<tr>
<th>Type</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Stateful</strong></td>
<td>Server stores session data</td>
</tr>
<tr>
<td><strong>Stateless</strong></td>
<td>Server does not store user state</td>
</tr>
</tbody></table>
<h3>Mapping</h3>
<ul>
<li><p><strong>Sessions → Stateful</strong></p>
</li>
<li><p><strong>JWT → Stateless</strong></p>
</li>
<li><p><strong>Cookies → Transport layer (used in both)</strong></p>
</li>
</ul>
<h2>Sessions vs JWT: Core Differences</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Sessions</th>
<th>JWT</th>
</tr>
</thead>
<tbody><tr>
<td>Storage</td>
<td>Server</td>
<td>Client</td>
</tr>
<tr>
<td>Type</td>
<td>Stateful</td>
<td>Stateless</td>
</tr>
<tr>
<td>Scalability</td>
<td>Harder (needs shared storage)</td>
<td>Easier</td>
</tr>
<tr>
<td>Performance</td>
<td>DB/cache lookup needed</td>
<td>No lookup</td>
</tr>
<tr>
<td>Revocation</td>
<td>Easy (delete session)</td>
<td>Hard</td>
</tr>
<tr>
<td>Payload size</td>
<td>Small (ID only)</td>
<td>Larger</td>
</tr>
<tr>
<td>Security control</td>
<td>Strong (server-controlled)</td>
<td>Depends on implementation</td>
</tr>
</tbody></table>
<h2>Where Cookies Fit In</h2>
<p>Cookies are used in <strong>both approaches</strong>:</p>
<table>
<thead>
<tr>
<th>Use Case</th>
<th>Role of Cookie</th>
</tr>
</thead>
<tbody><tr>
<td>Session-based auth</td>
<td>Stores session ID</td>
</tr>
<tr>
<td>JWT auth</td>
<td>Stores JWT token</td>
</tr>
<tr>
<td>Alternatives</td>
<td>JWT can also be sent via headers</td>
</tr>
</tbody></table>
<h2>Real-World Comparison</h2>
<h3>Session-Based Authentication</h3>
<p><strong>Best for:</strong></p>
<ul>
<li><p>Traditional web apps</p>
</li>
<li><p>Server-rendered apps</p>
</li>
<li><p>Admin dashboards</p>
</li>
</ul>
<p><strong>Why:</strong></p>
<ul>
<li><p>Easy to manage</p>
</li>
<li><p>Easy to revoke access</p>
</li>
<li><p>Strong control from server</p>
</li>
</ul>
<p><strong>Example Stack:</strong></p>
<ul>
<li>Express + express-session + Redis</li>
</ul>
<h3>JWT-Based Authentication</h3>
<p><strong>Best for:</strong></p>
<ul>
<li><p>APIs</p>
</li>
<li><p>Mobile apps</p>
</li>
<li><p>Microservices</p>
</li>
<li><p>Distributed systems</p>
</li>
</ul>
<p><strong>Why:</strong></p>
<ul>
<li><p>No shared session store needed</p>
</li>
<li><p>Works across services</p>
</li>
<li><p>Scales horizontally</p>
</li>
</ul>
<p><strong>Example Stack:</strong></p>
<ul>
<li>Node.js + JWT + Authorization headers</li>
</ul>
<h2>When to Use What (Decision Guide)</h2>
<h3>Use Sessions if:</h3>
<ul>
<li><p>You have a <strong>monolithic backend</strong></p>
</li>
<li><p>You want <strong>easy logout / revoke</strong></p>
</li>
<li><p>You prefer <strong>simplicity over scalability</strong></p>
</li>
</ul>
<h3>Use JWT if:</h3>
<ul>
<li><p>You’re building <strong>APIs for multiple clients</strong></p>
</li>
<li><p>You need <strong>stateless architecture</strong></p>
</li>
<li><p>You’re working with <strong>microservices</strong></p>
</li>
</ul>
<h3>Use Cookies if:</h3>
<ul>
<li><p>You want <strong>automatic request handling</strong></p>
</li>
<li><p>You're working with <strong>browser-based apps</strong></p>
</li>
</ul>
<h2>Practical Insight (What Most Beginners Miss)</h2>
<ul>
<li><p><strong>Cookies ≠ Authentication</strong></p>
</li>
<li><p><strong>JWT ≠ always better</strong></p>
</li>
<li><p><strong>Sessions are still widely used in production</strong></p>
</li>
</ul>
<p>A common modern setup:</p>
<p>👉 <strong>JWT stored inside HttpOnly cookies</strong></p>
<p>This combines:</p>
<ul>
<li><p>Security of cookies</p>
</li>
<li><p>Scalability of JWT</p>
</li>
</ul>
<h2>Final Comparison Table</h2>
<table>
<thead>
<tr>
<th>Aspect</th>
<th>Cookies</th>
<th>Sessions</th>
<th>JWT</th>
</tr>
</thead>
<tbody><tr>
<td>What it is</td>
<td>Storage mechanism</td>
<td>Server-side auth system</td>
<td>Token-based auth</td>
</tr>
<tr>
<td>Stored where</td>
<td>Client</td>
<td>Server</td>
<td>Client</td>
</tr>
<tr>
<td>Stateful?</td>
<td>N/A</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Needs DB lookup?</td>
<td>Depends</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Used with</td>
<td>Sessions / JWT</td>
<td>Cookies</td>
<td>Cookies / Headers</td>
</tr>
<tr>
<td>Scalability</td>
<td>N/A</td>
<td>Medium</td>
<td>High</td>
</tr>
</tbody></table>
<h3><strong>Mind Map ➡️</strong></h3>
<img src="https://cdn.hashnode.com/uploads/covers/69517129b3f42beb72514f64/e97c3e9b-b9f9-4794-bdce-febeaf7e6256.png" alt="" style="display:block;margin:0 auto" />

<h3>Conclusion</h3>
<ul>
<li><p><strong>Cookies</strong> = how data travels</p>
</li>
<li><p><strong>Sessions</strong> = server-managed identity</p>
</li>
<li><p><strong>JWT</strong> = self-contained identity</p>
</li>
</ul>
<p>There’s no “best” option — only <strong>context-appropriate choices</strong>.</p>
<p>If you're building:</p>
<ul>
<li><p>A simple web app → <strong>Sessions</strong></p>
</li>
<li><p>A scalable API → <strong>JWT</strong></p>
</li>
<li><p>A browser-based system → <strong>Cookies (with either approach)</strong></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Async Code in Node.js: Callbacks and Promises]]></title><description><![CDATA[When you first start working with Node.js, one concept keeps showing up everywhere: asynchronous code.
At first glance, it feels confusing — why not just run code line by line like normal programs?
Le]]></description><link>https://blogs.sayantanbal.in/async-code-in-node-js-callbacks-and-promises</link><guid isPermaLink="true">https://blogs.sayantanbal.in/async-code-in-node-js-callbacks-and-promises</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Sat, 25 Apr 2026 15:17:48 GMT</pubDate><content:encoded><![CDATA[<p>When you first start working with Node.js, one concept keeps showing up everywhere: <strong>asynchronous code</strong>.</p>
<p>At first glance, it feels confusing — why not just run code line by line like normal programs?</p>
<p>Let’s break it down step by step.</p>
<h2>Why Async Code Exists in Node.js</h2>
<p>Node.js is built on a <strong>single-threaded, non-blocking event loop architecture</strong>.</p>
<p>This means:</p>
<ul>
<li><p>It can handle many operations at once</p>
</li>
<li><p>But it does <strong>not</strong> create a new thread for each task</p>
</li>
</ul>
<p>Now imagine this scenario:</p>
<pre><code class="language-javascript">const data = fs.readFileSync("file.txt");
console.log(data);
console.log("Done");
</code></pre>
<p>This is <strong>blocking (synchronous)</strong>:</p>
<ul>
<li><p>Node waits for the file to be read</p>
</li>
<li><p>Nothing else happens during that time</p>
</li>
</ul>
<h3>Problem</h3>
<p>If file reading takes time:</p>
<ul>
<li><p>Your server is stuck</p>
</li>
<li><p>Other users have to wait</p>
</li>
</ul>
<h3>Solution: Asynchronous Code</h3>
<pre><code class="language-javascript">fs.readFile("file.txt", "utf-8", (err, data) =&gt; {
  console.log(data);
});

console.log("Done");
</code></pre>
<p>Now:</p>
<ul>
<li><p>Node <strong>does not wait</strong></p>
</li>
<li><p>It continues execution</p>
</li>
<li><p>Handles the result later</p>
</li>
</ul>
<h2>Real Scenario: File Reading</h2>
<p>Let’s understand the flow properly.</p>
<h3>Code:</h3>
<pre><code class="language-javascript">console.log("Start");

fs.readFile("file.txt", "utf-8", (err, data) =&gt; {
  if (err) {
    console.log("Error:", err);
    return;
  }
  console.log("File Data:", data);
});

console.log("End");
</code></pre>
<h3>Step-by-Step Execution</h3>
<ol>
<li><p><code>"Start"</code> is printed</p>
</li>
<li><p><code>fs.readFile</code> is sent to the system (async task)</p>
</li>
<li><p>Node <strong>does NOT wait</strong></p>
</li>
<li><p><code>"End"</code> is printed</p>
</li>
<li><p>Once file reading completes → callback executes</p>
</li>
<li><p><code>"File Data"</code> is printed</p>
</li>
</ol>
<h3>Output Order</h3>
<pre><code class="language-javascript">Start
End
File Data: ...
</code></pre>
<p>This is the <strong>core idea of async in Node.js</strong>.</p>
<h2>Callback-Based Async Execution</h2>
<p>A <strong>callback</strong> is simply:</p>
<blockquote>
<p>A function passed as an argument to another function, executed later.</p>
</blockquote>
<h3>Example:</h3>
<pre><code class="language-javascript">function fetchData(callback) {
  setTimeout(() =&gt; {
    callback("Data received");
  }, 1000);
}

fetchData((data) =&gt; {
  console.log(data);
});
</code></pre>
<h3>Key Idea</h3>
<ul>
<li><p>You give control to another function</p>
</li>
<li><p>It calls you back when work is done</p>
</li>
</ul>
<h2>Problem: Callback Hell</h2>
<p>Now let’s chain multiple async operations:</p>
<pre><code class="language-javascript">fs.readFile("file1.txt", "utf-8", (err, data1) =&gt; {
  fs.readFile("file2.txt", "utf-8", (err, data2) =&gt; {
    fs.readFile("file3.txt", "utf-8", (err, data3) =&gt; {
      console.log(data1, data2, data3);
    });
  });
});
</code></pre>
<h3>Issues</h3>
<ul>
<li><p>Deep nesting (pyramid shape)</p>
</li>
<li><p>Hard to read</p>
</li>
<li><p>Hard to debug</p>
</li>
<li><p>Error handling becomes messy</p>
</li>
</ul>
<p>This is called:</p>
<blockquote>
<p><strong>Callback Hell</strong> (or Pyramid of Doom)</p>
</blockquote>
<h2>Promise-Based Async Handling</h2>
<p>Promises were introduced to fix these problems.</p>
<h3>What is a Promise?</h3>
<p>A Promise represents:</p>
<blockquote>
<p>A value that will be available <strong>in the future</strong></p>
</blockquote>
<h3>States of a Promise</h3>
<ul>
<li><p><strong>Pending</strong></p>
</li>
<li><p><strong>Resolved (fulfilled)</strong></p>
</li>
<li><p><strong>Rejected</strong></p>
</li>
</ul>
<h3>Basic Example</h3>
<pre><code class="language-javascript">const promise = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; {
    resolve("Data received");
  }, 1000);
});

promise.then((data) =&gt; {
  console.log(data);
});
</code></pre>
<h2>Rewriting File Example Using Promises</h2>
<p>Using <code>fs.promises</code>:</p>
<pre><code class="language-javascript">const fs = require("fs").promises;

fs.readFile("file1.txt", "utf-8")
  .then((data1) =&gt; {
    return fs.readFile("file2.txt", "utf-8")
      .then((data2) =&gt; {
        return fs.readFile("file3.txt", "utf-8")
          .then((data3) =&gt; {
            console.log(data1, data2, data3);
          });
      });
  })
  .catch((err) =&gt; {
    console.log(err);
  });
</code></pre>
<h3>Better Version (Flat Chain)</h3>
<pre><code class="language-javascript">fs.readFile("file1.txt", "utf-8")
  .then((data1) =&gt; {
    console.log(data1);
    return fs.readFile("file2.txt", "utf-8");
  })
  .then((data2) =&gt; {
    console.log(data2);
    return fs.readFile("file3.txt", "utf-8");
  })
  .then((data3) =&gt; {
    console.log(data3);
  })
  .catch((err) =&gt; {
    console.log(err);
  });
</code></pre>
<h2>Benefits of Promises</h2>
<h3>1. Better Readability</h3>
<ul>
<li><p>No deep nesting</p>
</li>
<li><p>Linear flow</p>
</li>
</ul>
<h3>2. Centralised Error Handling</h3>
<pre><code class="language-js">.catch((err) =&gt; {
  console.log(err);
});
</code></pre>
<p>Instead of handling errors at every level.</p>
<h3>3. Easier Composition</h3>
<p>You can chain multiple async operations cleanly.</p>
<h3>4. Foundation for Async/Await</h3>
<p>Promises enable:</p>
<pre><code class="language-javascript">const data = await fs.readFile("file.txt", "utf-8");
</code></pre>
<h2>Callback vs Promise Comparison</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Callbacks</th>
<th>Promises</th>
</tr>
</thead>
<tbody><tr>
<td>Readability</td>
<td>Poor (nested)</td>
<td>Clean (chainable)</td>
</tr>
<tr>
<td>Error Handling</td>
<td>Scattered</td>
<td>Centralized (<code>.catch</code>)</td>
</tr>
<tr>
<td>Debugging</td>
<td>Difficult</td>
<td>Easier</td>
</tr>
<tr>
<td>Scalability</td>
<td>Poor</td>
<td>Better</td>
</tr>
<tr>
<td>Structure</td>
<td>Pyramid-like</td>
<td>Linear flow</td>
</tr>
</tbody></table>
<img src="https://cdn.hashnode.com/uploads/covers/69517129b3f42beb72514f64/a03a6410-44a7-4232-8009-6fb96670eb6e.png" alt="" style="display:block;margin:0 auto" />

<h2>Final Insight</h2>
<ul>
<li><p>Callbacks are <strong>low-level primitives</strong></p>
</li>
<li><p>Promises are <strong>structured abstractions</strong></p>
</li>
</ul>
<p>In modern Node.js:</p>
<blockquote>
<p>You should prefer <strong>Promises (and async/await)</strong> over callbacks</p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Linux Under the Hood: What I Discovered Exploring the File System Like a System Investigator]]></title><description><![CDATA[Most people start learning Linux by memorizing commands — ls, cd, mkdir, and so on. I did that too. But at some point, I realized something important:
Linux is not about commands. Linux is about struc]]></description><link>https://blogs.sayantanbal.in/linux-under-the-hood-what-i-discovered-exploring-the-file-system-like-a-system-investigator</link><guid isPermaLink="true">https://blogs.sayantanbal.in/linux-under-the-hood-what-i-discovered-exploring-the-file-system-like-a-system-investigator</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Mon, 20 Apr 2026 19:28:02 GMT</pubDate><content:encoded><![CDATA[<p>Most people start learning Linux by memorizing commands — <code>ls</code>, <code>cd</code>, <code>mkdir</code>, and so on. I did that too. But at some point, I realized something important:</p>
<p>Linux is not about commands. Linux is about <strong>structure</strong>.</p>
<p>Everything — networking, users, processes, devices — <em>is exposed through the file system</em>. So instead of practicing commands, I decided to <em>investigate the system itself</em>.</p>
<p>This blog is a collection of the most interesting things I discovered while exploring a real Linux environment. Each section focuses on <em>what exists, why it exists, and what problem it solves</em>.</p>
<h2>1. <code>/etc</code> — The Brain of System Configuration</h2>
<h3>What it is</h3>
<p><code>/etc</code> contains configuration files that control almost every aspect of system behaviour.</p>
<h3>Why it exists</h3>
<p>Instead of hardcoding system behaviour into binaries, Linux separates configuration from execution. This makes the system flexible and editable.</p>
<h3>What problem it solves</h3>
<ul>
<li><p>Allows admins to change system behaviour without recompiling software</p>
</li>
<li><p>Centralises configuration for easier debugging and auditing</p>
</li>
</ul>
<h3>What I found interesting</h3>
<p>Files like:</p>
<ul>
<li><p><code>/etc/hosts</code> → local DNS overrides</p>
</li>
<li><p><code>/etc/resolv.conf</code> → DNS server configuration</p>
</li>
<li><p><code>/etc/passwd</code> → user identity mapping</p>
</li>
</ul>
<p>This made me realise: Linux doesn’t hide its logic — it exposes it in plain text.</p>
<h2>2. DNS Resolution — <code>/etc/resolv.conf</code></h2>
<h3>What it is</h3>
<p>A file that defines which DNS servers your system uses.</p>
<h3>Why it exists</h3>
<p>When you type a domain (like google.com), your system needs a resolver to translate it into an IP address.</p>
<h3>What problem it solves</h3>
<ul>
<li><p>Enables domain name resolution</p>
</li>
<li><p>Allows custom DNS configuration (e.g., Google DNS, Cloudflare)</p>
</li>
</ul>
<h3>Insight</h3>
<p>I noticed that sometimes this file gets overwritten automatically (e.g., by NetworkManager or DHCP).</p>
<p>This taught me:</p>
<blockquote>
<p>DNS in Linux is not static — it's dynamically managed by networking services.</p>
</blockquote>
<h2>3. <code>/proc</code> — The Live System Mirror</h2>
<h3>What it is</h3>
<p>A virtual filesystem that exposes <strong>real-time system and process information</strong>.</p>
<h3>Why it exists</h3>
<p>Linux treats everything as a file — even running processes.</p>
<h3>What problem it solves</h3>
<ul>
<li><p><em>Provides introspection</em> into system state without special tools .</p>
</li>
<li><p>Allows programs to read kernel and process data easily .</p>
</li>
</ul>
<h3>What I found fascinating</h3>
<ul>
<li><p><code>/proc/cpuinfo</code> → CPU details</p>
</li>
<li><p><code>/proc/meminfo</code> → memory usage</p>
</li>
<li><p><code>/proc/&lt;pid&gt;/</code> → everything about a running process</p>
</li>
</ul>
<p>This changed my mental model completely:</p>
<blockquote>
<p>Processes are not abstract — they are <em>directories with data</em>.</p>
</blockquote>
<h2>4. <code>/dev</code> — Devices as Files</h2>
<h3>What it is</h3>
<p>A directory containing device files that represent hardware.</p>
<h3>Why it exists</h3>
<p>Linux uses a unified interface: <em>everything is treated as a file</em>, including hardware.</p>
<h3>What problem it solves</h3>
<ul>
<li><p>Standardises interaction with hardware .</p>
</li>
<li><p>Enables simple read/write operations for devices .</p>
</li>
</ul>
<h3>Examples</h3>
<ul>
<li><p><code>/dev/sda</code> → disk</p>
</li>
<li><p><code>/dev/null</code> → data sink</p>
</li>
<li><p><code>/dev/random</code> → entropy source</p>
</li>
</ul>
<h3>Insight</h3>
<p>Instead of using special APIs, programs interact with hardware using file operations.</p>
<p>That’s elegant system design.</p>
<h2>5. <code>/var/log</code> — The System’s Memory</h2>
<h3>What it is</h3>
<p>A directory storing logs generated by the system and services.</p>
<h3>Why it exists</h3>
<p>Systems need historical data to debug issues and monitor behaviour.</p>
<h3>What problem it solves</h3>
<ul>
<li><p>Debugging failures</p>
</li>
<li><p>Security auditing</p>
</li>
<li><p>Monitoring system activity</p>
</li>
</ul>
<h3>Interesting files</h3>
<ul>
<li><p><code>/var/log/syslog</code> or <code>/var/log/messages</code></p>
</li>
<li><p><code>/var/log/auth.log</code></p>
</li>
</ul>
<h3>Insight</h3>
<p>Logs are not just for debugging — they are <strong>evidence of system behavior over time</strong>.</p>
<h2>6. User Management — <code>/etc/passwd</code> &amp; <code>/etc/shadow</code></h2>
<h3>What they are</h3>
<ul>
<li><p><code>/etc/passwd</code> → user metadata</p>
</li>
<li><p><code>/etc/shadow</code> → encrypted passwords</p>
</li>
</ul>
<h3>Why they exist</h3>
<p>Separates identity from authentication for security.</p>
<h3>What problem they solve</h3>
<ul>
<li><p>Secure storage of credentials</p>
</li>
<li><p>System-wide user management</p>
</li>
</ul>
<h3>Insight</h3>
<p>Passwords are not stored in <code>/etc/passwd</code> anymore — that’s intentional for security.</p>
<p>Also, users are just structured entries — not “accounts” in the abstract sense.</p>
<h2>7. Permissions — The Real Security Layer</h2>
<h3>What it is</h3>
<p>Linux uses a permission model based on:</p>
<ul>
<li><p>Owner</p>
</li>
<li><p>Group</p>
</li>
<li><p>Others</p>
</li>
</ul>
<h3>Why it exists</h3>
<p>To enforce access control at the filesystem level.</p>
<h3>What problem it solves</h3>
<ul>
<li><p>Prevents unauthorised access</p>
</li>
<li><p>Controls execution and modification rights</p>
</li>
</ul>
<h3>Insight</h3>
<p>Permissions are not optional — they are <strong>core to Linux security</strong>.</p>
<p>Even root privileges operate within this model (though with override capability).</p>
<h2>8. <code>/boot</code> — The System’s Entry Point</h2>
<h3>What it is</h3>
<p>Contains files required to boot the system.</p>
<h3>Why it exists</h3>
<p>Before the OS runs, the system needs a minimal environment to start the kernel.</p>
<h3>What problem it solves</h3>
<ul>
<li><p>Initialises the OS</p>
</li>
<li><p>Loads the kernel and bootloader</p>
</li>
</ul>
<h3>Insight</h3>
<p>Files like:</p>
<ul>
<li><p>Kernel images</p>
</li>
<li><p>Bootloader configs (GRUB)</p>
</li>
</ul>
<p>This made me realise:</p>
<blockquote>
<p>Booting is just a staged file-loading process.</p>
</blockquote>
<h2>9. System Services — <code>/etc/systemd</code></h2>
<h3>What it is</h3>
<p>Configuration for system services managed by <code>systemd</code>.</p>
<h3>Why it exists</h3>
<p>Modern Linux systems need a structured way to manage background services.</p>
<h3>What problem it solves</h3>
<ul>
<li><p>Service lifecycle management</p>
</li>
<li><p>Dependency handling</p>
</li>
<li><p>Startup sequencing</p>
</li>
</ul>
<h3>Insight</h3>
<p>Services are defined declaratively using <code>.service</code> files.</p>
<p>Linux doesn’t “run things magically” — everything is explicitly defined.</p>
<h2>10. Networking Internals — Interfaces &amp; Routing</h2>
<h3>What I explored</h3>
<ul>
<li><p>Network interface configs</p>
</li>
<li><p>Routing tables</p>
</li>
<li><p>Kernel networking data</p>
</li>
</ul>
<h3>Where it lives</h3>
<ul>
<li><p><code>/proc/net/route</code> → routing table</p>
</li>
<li><p><code>/sys/class/net/</code> → interfaces</p>
</li>
</ul>
<h3>Why it exists</h3>
<p>Networking must be dynamically configurable and observable.</p>
<h3>What problem it solves</h3>
<ul>
<li><p>Packet routing</p>
</li>
<li><p>Interface management</p>
</li>
<li><p>Network diagnostics</p>
</li>
</ul>
<h3>Insight</h3>
<p>Routing is not abstract — it's literally a table the kernel follows.</p>
<h2>Final Realisation</h2>
<p>After exploring all these components, one idea became very clear:</p>
<blockquote>
<p>Linux is not a black box. It is a <strong>transparent system built on files and structure</strong>.</p>
</blockquote>
<ul>
<li><p>Processes → files</p>
</li>
<li><p>Devices → files</p>
</li>
<li><p>Configuration → files</p>
</li>
<li><p>System state → files</p>
</li>
</ul>
<p>Everything is inspectable.</p>
<h2>Why This Matters (Especially for Developers)</h2>
<p>Understanding the Linux filesystem at this level changes how you think about systems:</p>
<ul>
<li><p>Debugging becomes easier</p>
</li>
<li><p>Backend systems make more sense</p>
</li>
<li><p>DevOps concepts feel natural</p>
</li>
<li><p>You stop relying on tools blindly</p>
</li>
</ul>
<p>Instead of asking:</p>
<blockquote>
<p>“Which command should I use?”</p>
</blockquote>
<p>You start asking:</p>
<blockquote>
<p>“Where in the system is this behavior defined?”</p>
</blockquote>
<p>That’s a much more powerful mindset.</p>
<h2>Closing Thought</h2>
<p>This exploration made me realise that Linux is less about commands and more about <strong>philosophy</strong>:</p>
<blockquote>
<p><em>Expose everything. Keep it simple. Make it inspectable.</em></p>
</blockquote>
<p>And once you see that, you stop using Linux like a user — you start understanding it like a system engineer.</p>
]]></content:encoded></item><item><title><![CDATA[Map and Set in JavaScript]]></title><description><![CDATA[As JavaScript evolved, developers needed better data structures than traditional objects and arrays for certain use cases.
That’s where Map and Set come in.
They provide more control, better performan]]></description><link>https://blogs.sayantanbal.in/map-and-set-in-javascript</link><guid isPermaLink="true">https://blogs.sayantanbal.in/map-and-set-in-javascript</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Tue, 24 Mar 2026 10:19:21 GMT</pubDate><content:encoded><![CDATA[<p>As JavaScript evolved, developers needed better data structures than traditional <strong>objects</strong> and <strong>arrays</strong> for certain use cases.</p>
<p>That’s where <strong>Map</strong> and <strong>Set</strong> come in.</p>
<p>They provide more control, better performance in some cases, and cleaner semantics.</p>
<hr />
<h2>🔹 What is a Map?</h2>
<p>👉 A <strong>Map</strong> is a collection of <strong>key-value pairs</strong>, similar to objects—but with important differences.</p>
<h3>📌 Example</h3>
<pre><code class="language-js">const map = new Map();

map.set("name", "Sayantan");
map.set("age", 21);

console.log(map.get("name")); // Sayantan
</code></pre>
<hr />
<h3>🔹 Key Features of Map</h3>
<ul>
<li><p>Keys can be <strong>any data type</strong> (not just strings)</p>
</li>
<li><p>Maintains <strong>insertion order</strong></p>
</li>
<li><p>Has built-in methods like:</p>
<ul>
<li><p><code>.set()</code></p>
</li>
<li><p><code>.get()</code></p>
</li>
<li><p><code>.has()</code></p>
</li>
<li><p><code>.delete()</code></p>
</li>
</ul>
</li>
</ul>
<hr />
<h3>🔹 Example with Non-String Keys</h3>
<pre><code class="language-js">const map = new Map();

map.set(1, "Number key");
map.set(true, "Boolean key");

console.log(map.get(1)); // Number key
</code></pre>
<p>👉 This is NOT possible with normal objects.</p>
<hr />
<h2>🔹 What is a Set?</h2>
<p>👉 A <strong>Set</strong> is a collection of <strong>unique values</strong>.</p>
<p>It automatically removes duplicates.</p>
<hr />
<h3>📌 Example</h3>
<pre><code class="language-js">const set = new Set([1, 2, 2, 3, 4]);

console.log(set); // {1, 2, 3, 4}
</code></pre>
<hr />
<h3>🔹 Key Features of Set</h3>
<ul>
<li><p>Stores <strong>only unique values</strong></p>
</li>
<li><p>No duplicate entries</p>
</li>
<li><p>Maintains insertion order</p>
</li>
<li><p>Useful methods:</p>
<ul>
<li><p><code>.add()</code></p>
</li>
<li><p><code>.has()</code></p>
</li>
<li><p><code>.delete()</code></p>
</li>
</ul>
</li>
</ul>
<hr />
<h3>🔹 Example: Removing Duplicates</h3>
<pre><code class="language-js">const arr = [1, 2, 2, 3];

const unique = [...new Set(arr)];

console.log(unique); // [1, 2, 3]
</code></pre>
<hr />
<h2>🔥 Map vs Object</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Map</th>
<th>Object</th>
</tr>
</thead>
<tbody><tr>
<td>Key Types</td>
<td>Any type</td>
<td>Strings/Symbols only</td>
</tr>
<tr>
<td>Order</td>
<td>Maintains order</td>
<td>Not guaranteed (historically)</td>
</tr>
<tr>
<td>Iteration</td>
<td>Easy (<code>for...of</code>)</td>
<td>Requires extra methods</td>
</tr>
<tr>
<td>Performance</td>
<td>Better for frequent updates</td>
<td>Good for simple use cases</td>
</tr>
</tbody></table>
<hr />
<h3>📌 Problem with Objects</h3>
<pre><code class="language-js">const obj = {};

obj[1] = "Number key";

console.log(obj["1"]); // "Number key"
</code></pre>
<p>👉 Keys are converted to strings → loss of flexibility</p>
<hr />
<h2>🔥 Set vs Array</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Set</th>
<th>Array</th>
</tr>
</thead>
<tbody><tr>
<td>Duplicates</td>
<td>Not allowed</td>
<td>Allowed</td>
</tr>
<tr>
<td>Order</td>
<td>Maintained</td>
<td>Maintained</td>
</tr>
<tr>
<td>Access</td>
<td>No index</td>
<td>Index-based</td>
</tr>
<tr>
<td>Use Case</td>
<td>Unique values</td>
<td>Ordered data</td>
</tr>
</tbody></table>
<hr />
<h3>📌 Problem with Arrays</h3>
<pre><code class="language-js">const arr = [1, 2, 2, 3];

const unique = arr.filter((item, index) =&gt; arr.indexOf(item) === index);

console.log(unique); // [1, 2, 3]
</code></pre>
<p>❌ Complex ❌ Inefficient</p>
<p>✔ Set solves this easily</p>
<hr />
<h2>🔹 When to Use Map</h2>
<p>Use <strong>Map</strong> when:</p>
<ul>
<li><p>You need <strong>key-value storage</strong></p>
</li>
<li><p>Keys are <strong>not strings</strong></p>
</li>
<li><p>Frequent additions/deletions</p>
</li>
<li><p>Need guaranteed <strong>insertion order</strong></p>
</li>
</ul>
<hr />
<h3>📌 Real Example</h3>
<pre><code class="language-js">const userRoles = new Map();

userRoles.set("Sayantan", "Admin");
userRoles.set("Rahul", "User");

console.log(userRoles.get("Sayantan"));
</code></pre>
<hr />
<h2>🔹 When to Use Set</h2>
<p>Use <strong>Set</strong> when:</p>
<ul>
<li><p>You need <strong>unique values</strong></p>
</li>
<li><p>Removing duplicates</p>
</li>
<li><p>Checking existence quickly</p>
</li>
</ul>
<hr />
<h3>📌 Real Example</h3>
<pre><code class="language-js">const visitedPages = new Set();

visitedPages.add("/home");
visitedPages.add("/about");
visitedPages.add("/home");

console.log(visitedPages); // no duplicates
</code></pre>
<hr />
<h2>🧠 Mental Model</h2>
<ul>
<li><p><strong>Map → advanced object (key-value storage)</strong></p>
</li>
<li><p><strong>Set → advanced array (unique values)</strong></p>
</li>
</ul>
<hr />
<h2>🚀 Practical Use Cases</h2>
<h3>1. Remove Duplicates</h3>
<pre><code class="language-js">const nums = [1, 2, 2, 3];

const uniqueNums = [...new Set(nums)];
</code></pre>
<hr />
<h3>2. Fast Lookup</h3>
<pre><code class="language-js">const set = new Set([1, 2, 3]);

console.log(set.has(2)); // true
</code></pre>
<hr />
<h3>3. Dynamic Key Storage</h3>
<pre><code class="language-js">const map = new Map();

const objKey = { id: 1 };

map.set(objKey, "Data");

console.log(map.get(objKey)); // Data
</code></pre>
<hr />
<h2>⚠️ Common Mistakes</h2>
<h3>❌ Using Object Instead of Map</h3>
<pre><code class="language-js">const obj = {};

obj[{ id: 1 }] = "value";

console.log(obj); // "[object Object]"
</code></pre>
<p>👉 Key gets stringified → incorrect behavior</p>
<hr />
<h3>❌ Expecting Index in Set</h3>
<pre><code class="language-js">const set = new Set([10, 20, 30]);

console.log(set[0]); // undefined ❌
</code></pre>
<p>👉 Sets don’t support indexing</p>
]]></content:encoded></item><item><title><![CDATA[Destructuring in JavaScript]]></title><description><![CDATA[In JavaScript, working with arrays and objects often involves extracting values. Traditionally, this required repetitive code.
Destructuring solves this problem by allowing you to unpack values from a]]></description><link>https://blogs.sayantanbal.in/destructuring-in-javascript</link><guid isPermaLink="true">https://blogs.sayantanbal.in/destructuring-in-javascript</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Tue, 24 Mar 2026 10:18:34 GMT</pubDate><content:encoded><![CDATA[<p>In JavaScript, working with arrays and objects often involves extracting values. Traditionally, this required repetitive code.</p>
<p><strong>Destructuring</strong> solves this problem by allowing you to <strong>unpack values from arrays or objects into variables in a clean and concise way</strong>.</p>
<hr />
<h2>🔹 What is Destructuring?</h2>
<p>👉 <strong>Destructuring = breaking down complex data structures (arrays/objects) into smaller variables</strong></p>
<p>Instead of accessing values one by one, you can extract them in a single line.</p>
<hr />
<h2>🔹 Before vs After Destructuring</h2>
<h3>❌ Without Destructuring</h3>
<pre><code class="language-js">const user = {
  name: "Sayantan",
  age: 21
};

const name = user.name;
const age = user.age;
</code></pre>
<hr />
<h3>✅ With Destructuring</h3>
<pre><code class="language-js">const user = {
  name: "Sayantan",
  age: 21
};

const { name, age } = user;
</code></pre>
<p>✔ Less code ✔ Cleaner ✔ More readable</p>
<hr />
<h2>🔹 Destructuring Arrays</h2>
<p>Array destructuring is based on <strong>position (index)</strong>.</p>
<h3>📌 Example</h3>
<pre><code class="language-js">const arr = [10, 20, 30];

const [a, b, c] = arr;

console.log(a); // 10
console.log(b); // 20
console.log(c); // 30
</code></pre>
<hr />
<h3>🔹 Skipping Values</h3>
<pre><code class="language-js">const arr = [10, 20, 30];

const [first, , third] = arr;

console.log(first); // 10
console.log(third); // 30
</code></pre>
<hr />
<h3>🔹 Using Rest Operator</h3>
<pre><code class="language-js">const arr = [1, 2, 3, 4];

const [first, ...rest] = arr;

console.log(first); // 1
console.log(rest);  // [2, 3, 4]
</code></pre>
<hr />
<h2>🔹 Destructuring Objects</h2>
<p>Object destructuring is based on <strong>property names</strong>, not position.</p>
<h3>📌 Example</h3>
<pre><code class="language-js">const user = {
  name: "Sayantan",
  age: 21,
  city: "Kolkata"
};

const { name, age } = user;

console.log(name); // Sayantan
console.log(age);  // 21
</code></pre>
<hr />
<h3>🔹 Renaming Variables</h3>
<pre><code class="language-js">const user = {
  name: "Sayantan"
};

const { name: userName } = user;

console.log(userName); // Sayantan
</code></pre>
<hr />
<h3>🔹 Nested Destructuring</h3>
<pre><code class="language-js">const user = {
  name: "Sayantan",
  address: {
    city: "Kolkata"
  }
};

const {
  address: { city }
} = user;

console.log(city); // Kolkata
</code></pre>
<hr />
<h2>🔹 Default Values</h2>
<p>If a value is missing, you can assign a default.</p>
<pre><code class="language-js">const user = {
  name: "Sayantan"
};

const { name, age = 18 } = user;

console.log(name); // Sayantan
console.log(age);  // 18
</code></pre>
<hr />
<h2>🔹 Destructuring in Function Parameters</h2>
<pre><code class="language-js">function greet({ name, age }) {
  console.log(`Hello \({name}, age \){age}`);
}

greet({ name: "Sayantan", age: 21 });
</code></pre>
<p>✔ Very common in real-world code (especially React)</p>
<hr />
<h2>🔹 Benefits of Destructuring</h2>
<h3>✅ 1. Reduces Repetitive Code</h3>
<pre><code class="language-js">// Without
const name = user.name;
const age = user.age;

// With
const { name, age } = user;
</code></pre>
<hr />
<h3>✅ 2. Improves Readability</h3>
<p>Cleaner and easier to understand structure.</p>
<hr />
<h3>✅ 3. Makes Code More Expressive</h3>
<p>You clearly see what data is being used.</p>
<hr />
<h3>✅ 4. Useful in Modern JavaScript</h3>
<ul>
<li><p>React props</p>
</li>
<li><p>API responses</p>
</li>
<li><p>Function arguments</p>
</li>
</ul>
<hr />
<h2>🔹 Real-World Example</h2>
<pre><code class="language-js">const response = {
  data: {
    user: {
      name: "Sayantan",
      age: 21
    }
  }
};

const {
  data: {
    user: { name, age }
  }
} = response;

console.log(name, age);
</code></pre>
<hr />
<h2>⚠️ Common Mistakes</h2>
<h3>❌ Wrong Variable Names</h3>
<pre><code class="language-js">const user = { name: "Sayantan" };

const { username } = user; // ❌ undefined
</code></pre>
<p>✔ Must match property name</p>
<hr />
<h3>❌ Accessing Nested Without Safety</h3>
<pre><code class="language-js">const user = {};

const {
  address: { city }
} = user; // ❌ error
</code></pre>
<p>✔ Use optional chaining or defaults</p>
<hr />
<h2>🧠 Mental Model</h2>
<ul>
<li><p><strong>Array destructuring → position-based</strong></p>
</li>
<li><p><strong>Object destructuring → key-based</strong></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[JavaScript Promises Explained for Beginners]]></title><description><![CDATA[As JavaScript applications became more complex, handling asynchronous operations using callbacks started creating messy, hard-to-maintain code.
This is where Promises come in.
They provide a cleaner a]]></description><link>https://blogs.sayantanbal.in/javascript-promises-explained-for-beginners</link><guid isPermaLink="true">https://blogs.sayantanbal.in/javascript-promises-explained-for-beginners</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Tue, 24 Mar 2026 10:17:06 GMT</pubDate><content:encoded><![CDATA[<p>As JavaScript applications became more complex, handling asynchronous operations using <strong>callbacks</strong> started creating messy, hard-to-maintain code.</p>
<p>This is where <strong>Promises</strong> come in.</p>
<p>They provide a cleaner and more structured way to handle asynchronous operations.</p>
<hr />
<h2>🔹 What Problem Do Promises Solve?</h2>
<h3>🚨 Callback Hell</h3>
<pre><code class="language-js">getUser(function(user) {
  getOrders(user.id, function(orders) {
    getOrderDetails(orders[0], function(details) {
      console.log(details);
    });
  });
});
</code></pre>
<p>❌ Deep nesting ❌ Hard to read ❌ Difficult to debug</p>
<hr />
<h3>✅ With Promises</h3>
<pre><code class="language-js">getUser()
  .then(user =&gt; getOrders(user.id))
  .then(orders =&gt; getOrderDetails(orders[0]))
  .then(details =&gt; console.log(details))
  .catch(err =&gt; console.error(err));
</code></pre>
<p>✔ Flat structure ✔ Better readability ✔ Easier error handling</p>
<hr />
<h2>🔹 What is a Promise?</h2>
<p>👉 A <strong>Promise is a placeholder for a value that will be available in the future</strong>.</p>
<p>Think of it like:</p>
<blockquote>
<p>"I don’t have the data right now, but I promise I’ll give it to you later."</p>
</blockquote>
<hr />
<h2>🔹 Promise States</h2>
<p>A promise has <strong>3 states</strong>:</p>
<ol>
<li><p><strong>Pending</strong></p>
<ul>
<li><p>Initial state</p>
</li>
<li><p>Operation not completed yet</p>
</li>
</ul>
</li>
<li><p><strong>Fulfilled</strong></p>
<ul>
<li><p>Operation successful</p>
</li>
<li><p>Value is available</p>
</li>
</ul>
</li>
<li><p><strong>Rejected</strong></p>
<ul>
<li><p>Operation failed</p>
</li>
<li><p>Error is returned</p>
</li>
</ul>
</li>
</ol>
<hr />
<h3>📌 Example</h3>
<pre><code class="language-js">const promise = new Promise((resolve, reject) =&gt; {
  const success = true;

  if (success) {
    resolve("Data fetched");
  } else {
    reject("Error occurred");
  }
});
</code></pre>
<hr />
<h2>🔹 Basic Promise Lifecycle</h2>
<pre><code class="language-js">const promise = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; {
    resolve("Done!");
  }, 2000);
});

promise
  .then(result =&gt; console.log(result))  // success
  .catch(error =&gt; console.error(error)) // failure
  .finally(() =&gt; console.log("Finished"));
</code></pre>
<hr />
<h3>🔍 Flow</h3>
<ol>
<li><p>Promise starts → <strong>Pending</strong></p>
</li>
<li><p>After 2 sec → <strong>Fulfilled</strong></p>
</li>
<li><p><code>.then()</code> runs</p>
</li>
<li><p><code>.finally()</code> always runs</p>
</li>
</ol>
<hr />
<h2>🔹 Handling Success and Failure</h2>
<pre><code class="language-js">fetchData()
  .then(data =&gt; {
    console.log("Success:", data);
  })
  .catch(error =&gt; {
    console.log("Error:", error);
  });
</code></pre>
<p>✔ <code>.then()</code> → handles success ✔ <code>.catch()</code> → handles errors</p>
<hr />
<h2>🔹 Promise Chaining</h2>
<p>Promises allow <strong>sequential execution without nesting</strong>.</p>
<pre><code class="language-js">getUser()
  .then(user =&gt; getOrders(user.id))
  .then(orders =&gt; getOrdersDetails(orders))
  .then(details =&gt; console.log(details))
  .catch(err =&gt; console.error(err));
</code></pre>
<p>👉 Each <code>.then()</code> returns a new promise</p>
<hr />
<h3>🔥 Why Chaining Works</h3>
<ul>
<li><p>Each step waits for the previous one</p>
</li>
<li><p>No pyramid structure</p>
</li>
<li><p>Cleaner and more readable</p>
</li>
</ul>
<hr />
<h2>🔹 Real-World Example</h2>
<pre><code class="language-js">fetch("https://jsonplaceholder.typicode.com/posts/1")
  .then(res =&gt; res.json())
  .then(data =&gt; console.log(data))
  .catch(err =&gt; console.error(err));
</code></pre>
<hr />
<h2>🔹 Promises vs Callbacks</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Callbacks</th>
<th>Promises</th>
</tr>
</thead>
<tbody><tr>
<td>Structure</td>
<td>Nested</td>
<td>Flat (chained)</td>
</tr>
<tr>
<td>Readability</td>
<td>Poor</td>
<td>Good</td>
</tr>
<tr>
<td>Error Handling</td>
<td>Manual</td>
<td>Centralized (<code>catch</code>)</td>
</tr>
<tr>
<td>Maintainability</td>
<td>Difficult</td>
<td>Easier</td>
</tr>
</tbody></table>
<hr />
<h2>🔹 Mental Model</h2>
<ul>
<li><p>Promise = <strong>future value</strong></p>
</li>
<li><p><code>.then()</code> = "When it's ready, do this"</p>
</li>
<li><p><code>.catch()</code> = "If it fails, handle it"</p>
</li>
</ul>
<hr />
<h2>🔹 Common Mistakes</h2>
<h3>❌ Not Returning Promise in Chain</h3>
<pre><code class="language-js">getUser()
  .then(user =&gt; {
    getOrders(user.id); // ❌ missing return
  })
  .then(orders =&gt; console.log(orders)); // undefined
</code></pre>
<p>✔ Always return the promise</p>
<hr />
<h3>❌ Multiple .then without Chain</h3>
<pre><code class="language-js">promise.then(a =&gt; console.log(a));
promise.then(b =&gt; console.log(b));
</code></pre>
<p>👉 Runs independently (not sequential)</p>
<hr />
<h2>🚀 Why Promises Matter</h2>
<ul>
<li><p>Foundation of modern async JavaScript</p>
</li>
<li><p>Used in:</p>
<ul>
<li><p>APIs (<code>fetch</code>)</p>
</li>
<li><p>Databases</p>
</li>
<li><p>File systems</p>
</li>
</ul>
</li>
<li><p>Base for <strong>async/await</strong></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Synchronous vs Asynchronous JavaScript]]></title><description><![CDATA[Understanding how JavaScript executes code is one of the most fundamental concepts you need as a developer.
At the core, JavaScript can execute code in two ways:

Synchronous (blocking)

Asynchronous ]]></description><link>https://blogs.sayantanbal.in/synchronous-vs-asynchronous-javascript</link><guid isPermaLink="true">https://blogs.sayantanbal.in/synchronous-vs-asynchronous-javascript</guid><dc:creator><![CDATA[Sayantan]]></dc:creator><pubDate>Tue, 24 Mar 2026 10:16:25 GMT</pubDate><content:encoded><![CDATA[<p>Understanding how JavaScript executes code is one of the most fundamental concepts you need as a developer.</p>
<p>At the core, JavaScript can execute code in <strong>two ways</strong>:</p>
<ul>
<li><p><strong>Synchronous (blocking)</strong></p>
</li>
<li><p><strong>Asynchronous (non-blocking)</strong></p>
</li>
</ul>
<p>Let’s break this down step by step in a very intuitive way.</p>
<hr />
<h2>🔹 What is Synchronous Code?</h2>
<p><strong>Synchronous code executes line by line, one after another.</strong></p>
<p>👉 Each line must finish before the next one starts.</p>
<h3>📌 Example</h3>
<pre><code class="language-js">console.log("Start");

console.log("Middle");

console.log("End");
</code></pre>
<h3>🧠 Output</h3>
<pre><code class="language-plaintext">Start
Middle
End
</code></pre>
<h3>🔍 Explanation</h3>
<ul>
<li><p>JavaScript executes the first line</p>
</li>
<li><p>Then moves to the next</p>
</li>
<li><p>No skipping, no waiting</p>
</li>
</ul>
<p>✔ Simple ✔ Predictable ❌ Can become slow if a task takes too long</p>
<hr />
<h2>🔹 What is Asynchronous Code?</h2>
<p><strong>Asynchronous code allows JavaScript to perform tasks without blocking the main thread.</strong></p>
<p>👉 It can start a task and move on without waiting for it to finish.</p>
<hr />
<h3>📌 Example with Timer</h3>
<pre><code class="language-js">console.log("Start");

setTimeout(() =&gt; {
  console.log("Inside Timeout");
}, 2000);

console.log("End");
</code></pre>
<h3>🧠 Output</h3>
<pre><code class="language-plaintext">Start
End
Inside Timeout
</code></pre>
<hr />
<h3>🔍 Explanation</h3>
<ul>
<li><p><code>setTimeout</code> is asynchronous</p>
</li>
<li><p>JavaScript <strong>does not wait</strong> for 2 seconds</p>
</li>
<li><p>It moves to the next line immediately</p>
</li>
</ul>
<p>✔ Faster ✔ Efficient ✔ Non-blocking</p>
<hr />
<h2>🔥 Synchronous vs Asynchronous (Core Difference)</h2>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Synchronous</th>
<th>Asynchronous</th>
</tr>
</thead>
<tbody><tr>
<td>Execution</td>
<td>Line by line</td>
<td>Does not wait</td>
</tr>
<tr>
<td>Blocking</td>
<td>Yes (blocking)</td>
<td>No (non-blocking)</td>
</tr>
<tr>
<td>Performance</td>
<td>Can be slow</td>
<td>More efficient</td>
</tr>
<tr>
<td>Use Case</td>
<td>Simple tasks</td>
<td>API calls, timers, I/O</td>
</tr>
</tbody></table>
<hr />
<h2>🔹 Why JavaScript Needs Asynchronous Behavior</h2>
<p>JavaScript is <strong>single-threaded</strong>.</p>
<p>👉 It can do <strong>only one thing at a time</strong>.</p>
<p>So imagine this situation:</p>
<h3>❌ Without Async (Blocking)</h3>
<pre><code class="language-js">console.log("Start");

// Simulating heavy work
for (let i = 0; i &lt; 1e9; i++) {}

console.log("End");
</code></pre>
<p>⛔ The browser freezes ⛔ User cannot interact ⛔ Bad user experience</p>
<hr />
<h3>✅ With Async</h3>
<pre><code class="language-js">console.log("Start");

setTimeout(() =&gt; {
  console.log("Heavy task done");
}, 0);

console.log("End");
</code></pre>
<p>✔ UI remains responsive ✔ Tasks handled efficiently</p>
<hr />
<h2>🔹 Real-World Example: API Call</h2>
<h3>❌ If It Were Synchronous</h3>
<pre><code class="language-js">const data = fetch("https://api.com/data"); // imagine blocking

console.log(data);
</code></pre>
<p>👉 The app would freeze until data arrives</p>
<hr />
<h3>✅ Actual Async Behavior</h3>
<pre><code class="language-js">fetch("https://api.com/data")
  .then(res =&gt; res.json())
  .then(data =&gt; console.log(data));
</code></pre>
<p>✔ App continues running ✔ Data comes later</p>
<hr />
<h2>🔹 Blocking vs Non-Blocking (Simple Analogy)</h2>
<h3>☕ Real Life Example</h3>
<ul>
<li><p><strong>Synchronous</strong> → Ordering coffee and waiting at the counter until it's ready</p>
</li>
<li><p><strong>Asynchronous</strong> → Ordering coffee, getting a token, and sitting down while it’s prepared</p>
</li>
</ul>
<p>👉 Which is better? Obviously async.</p>
<hr />
<h2>🔹 How JavaScript Handles Async Internally</h2>
<p>Even though JavaScript is single-threaded, it uses:</p>
<ul>
<li><p><strong>Call Stack</strong> → Executes functions</p>
</li>
<li><p><strong>Web APIs</strong> → Handle async tasks (timers, fetch)</p>
</li>
<li><p><strong>Callback Queue</strong> → Stores completed async tasks</p>
</li>
<li><p><strong>Event Loop</strong> → Moves tasks back to execution</p>
</li>
</ul>
<p>👉 This system makes async possible.</p>
<hr />
<h2>🔹 Problems with Blocking Code</h2>
<ol>
<li><p><strong>Freezes UI</strong></p>
</li>
<li><p><strong>Bad user experience</strong></p>
</li>
<li><p><strong>Slow performance</strong></p>
</li>
<li><p><strong>Unresponsive applications</strong></p>
</li>
</ol>
<hr />
<h2>🔹 When to Use What?</h2>
<h3>Use Synchronous:</h3>
<ul>
<li><p>Simple calculations</p>
</li>
<li><p>Small tasks</p>
</li>
</ul>
<h3>Use Asynchronous:</h3>
<ul>
<li><p>API calls</p>
</li>
<li><p>File handling</p>
</li>
<li><p>Timers</p>
</li>
<li><p>Database operations</p>
</li>
</ul>
<hr />
<h2>🧠 Mental Model</h2>
<ul>
<li><p><strong>Synchronous → "Wait and do"</strong></p>
</li>
<li><p><strong>Asynchronous → "Start and move on"</strong></p>
</li>
</ul>
]]></content:encoded></item></channel></rss>