<?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[Decode with Harsh]]></title><description><![CDATA[Decode with Harsh]]></description><link>https://blog.harshx.in</link><generator>RSS for Node</generator><lastBuildDate>Wed, 27 May 2026 04:46:18 GMT</lastBuildDate><atom:link href="https://blog.harshx.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Understanding the this Keyword in JavaScript
]]></title><description><![CDATA[this = most confusing JavaScript concept. What this refer to? Depend on who call function. Caller = this. Understand caller, understand this.
This about this keyword and how it change.

What this Repr]]></description><link>https://blog.harshx.in/understanding-the-this-in-javascript</link><guid isPermaLink="true">https://blog.harshx.in/understanding-the-this-in-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 12:28:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/c8ca2b69-b8b3-4253-9f05-1b1b6f31589f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><code>this</code> = most confusing JavaScript concept. What <code>this</code> refer to? Depend on who call function. Caller = <code>this</code>. Understand caller, understand <code>this</code>.</p>
<p>This about <code>this</code> keyword and how it change.</p>
<hr />
<h2>What this Represents</h2>
<p><code>this</code> = reference to caller. Who call function? That who <code>this</code> is.</p>
<h3>Simple Definition</h3>
<p><code>this</code> = the object that calling the function. Not the function itself. The thing that call it.</p>
<h3>Real Analogy</h3>
<p>Waiter in restaurant:</p>
<pre><code>Customer say "I want coffee"
Waiter say "Who want coffee?"
Customer say "Me, I want coffee"

So "I" = the customer (the caller)
</code></pre>
<p>In JavaScript:</p>
<pre><code class="language-javascript">user.greet()  // user calling greet()
              // So "this" inside greet = user
</code></pre>
<p><code>this</code> = who call the method.</p>
<h3>Why this Matter</h3>
<p><code>this</code> let function know who calling it. Function can behave different for different callers.</p>
<pre><code class="language-javascript">const user1 = {
  name: 'Alice',
  greet() {
    console.log(`Hello, I'm ${this.name}`);
  }
};

const user2 = {
  name: 'Bob',
  greet() {
    console.log(`Hello, I'm ${this.name}`);
  }
};

user1.greet();  // "Hello, I'm Alice"
                // this = user1

user2.greet();  // "Hello, I'm Bob"
                // this = user2
</code></pre>
<p>Same function logic. Different <code>this</code>. Different output.</p>
<hr />
<h2>this in Global Context</h2>
<p>In global scope, <code>this</code> = global object.</p>
<h3>Browser Global</h3>
<p>In browser, global object = <code>window</code>.</p>
<pre><code class="language-javascript">console.log(this);  // window (in browser)
console.log(this === window);  // true

console.log(this.innerHeight);  // window.innerHeight
</code></pre>
<p>Top level code run in window context. So <code>this</code> = window.</p>
<h3>Node.js Global</h3>
<p>In Node.js, global object = <code>global</code> (or module context).</p>
<pre><code class="language-javascript">console.log(this);  // {} (module context in Node.js)
                    // NOT global in strict module

console.log(global);  // global object
</code></pre>
<p>Node.js = different. But usually don't use <code>this</code> in global scope.</p>
<h3>Function in Global Scope</h3>
<pre><code class="language-javascript">function greet() {
  console.log(this);
}

greet();  // Browser: window
          // Node.js: global (in strict mode: undefined)
</code></pre>
<p>No caller = default caller = global object.</p>
<h3>Problem: Losing this</h3>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  greet() {
    console.log(this.name);
  }
};

const func = user.greet;  // Extract method
func();  // undefined (or error)

// Why?
// func() have no caller object
// So this = global or undefined
// global.name = undefined
</code></pre>
<p>When extract method = lose context = lose <code>this</code>.</p>
<hr />
<h2>this Inside Objects</h2>
<p><code>this</code> = the object calling method.</p>
<h3>Method Call</h3>
<p>Object call its own method. <code>this</code> = object.</p>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  age: 25,
  
  greet() {
    console.log(`I'm ${this.name}`);
  },
  
  haveBirthday() {
    this.age++;
    console.log(`Now ${this.age}`);
  }
};

user.greet();         // this = user
                      // "I'm Alice"

user.haveBirthday();  // this = user
                      // Now 26
</code></pre>
<p><code>user.greet()</code> = user calling greet = this = user.</p>
<h3>Accessing Object Properties</h3>
<p>Method use <code>this</code> to access own properties.</p>
<pre><code class="language-javascript">const car = {
  brand: 'Toyota',
  speed: 0,
  
  accelerate() {
    this.speed += 10;
    console.log(`\({this.brand} speed: \){this.speed}`);
  }
};

car.accelerate();  // "Toyota speed: 10"
car.accelerate();  // "Toyota speed: 20"

console.log(car.speed);  // 20
</code></pre>
<p><code>this.speed</code> refer to car's speed property.
<code>this.brand</code> refer to car's brand property.</p>
<h3>Multiple Objects, Same Method</h3>
<pre><code class="language-javascript">const person1 = {
  name: 'Alice',
  introduce() {
    console.log(`I'm ${this.name}`);
  }
};

const person2 = {
  name: 'Bob',
  introduce() {
    console.log(`I'm ${this.name}`);
  }
};

person1.introduce();  // "I'm Alice" (this = person1)
person2.introduce();  // "I'm Bob"   (this = person2)
</code></pre>
<p>Different objects, same method logic. <code>this</code> different.</p>
<h3>Nested Objects</h3>
<pre><code class="language-javascript">const company = {
  name: 'TechCorp',
  owner: {
    name: 'Alice',
    greet() {
      console.log(`I'm ${this.name}`);  // this = owner (not company)
    }
  }
};

company.owner.greet();  // "I'm Alice"
                        // this = owner object (immediate caller)
</code></pre>
<p><code>this</code> = immediate caller. Not parent object.</p>
<hr />
<h2>this Inside Functions</h2>
<p>Function context different from object context.</p>
<h3>Regular Function Call</h3>
<pre><code class="language-javascript">function greet() {
  console.log(this);
}

greet();  // Browser: window
          // Node.js: undefined (strict mode) or global

// No object call it = default context
</code></pre>
<p>Function standalone = no object caller = <code>this</code> = global or undefined.</p>
<h3>Function with Caller</h3>
<pre><code class="language-javascript">const user = { name: 'Alice' };

function greet() {
  console.log(`Hi, I'm ${this.name}`);
}

// Call function with user context
greet.call(user);  // "Hi, I'm Alice"
                   // Force this = user
</code></pre>
<p><code>.call()</code> = force who caller is.</p>
<h3>Method vs Function</h3>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  
  method() {
    console.log(this.name);  // this = user (method call)
  },
  
  getFunction() {
    function inner() {
      console.log(this.name);  // this = global/undefined (function call)
    }
    return inner;
  }
};

user.method();        // "Alice" (this = user)

const func = user.getFunction();
func();               // undefined (this = global)
</code></pre>
<p>Method = <code>this</code> = caller.
Nested function = <code>this</code> = global (lose context).</p>
<hr />
<h2>How Calling Context Change this</h2>
<p><code>this</code> depend on how function called. Three way to call function.</p>
<h3>1. Method Call: obj.func()</h3>
<p>Object call function. <code>this</code> = object.</p>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  greet() {
    console.log(`Hi, ${this.name}`);
  }
};

user.greet();  // this = user
</code></pre>
<h3>2. Function Call: func()</h3>
<p>Direct call. <code>this</code> = global (or undefined in strict).</p>
<pre><code class="language-javascript">function greet() {
  console.log(this);
}

greet();  // this = window (browser) or undefined (strict mode)
</code></pre>
<h3>3. Using .call() or .apply()</h3>
<p>Explicitly set <code>this</code>.</p>
<pre><code class="language-javascript">const user1 = { name: 'Alice' };
const user2 = { name: 'Bob' };

function greet() {
  console.log(`Hi, ${this.name}`);
}

greet.call(user1);   // this = user1 → "Hi, Alice"
greet.call(user2);   // this = user2 → "Hi, Bob"
</code></pre>
<p><code>.call(obj)</code> = call function with <code>this</code> = obj.</p>
<h3>Difference Visualized</h3>
<pre><code>user.greet()
  │
  └─ user calling greet
     └─ this = user

greet()
  │
  └─ no one calling (function call)
     └─ this = global

greet.call(user)
  │
  └─ explicitly set caller
     └─ this = user
</code></pre>
<p>Same function. Different caller. Different <code>this</code>.</p>
<hr />
<h2>Arrow Functions and this</h2>
<p>Arrow function different from regular function. Arrow function = inherit <code>this</code> from outer scope.</p>
<h3>Regular Function</h3>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  
  greet() {
    function inner() {
      console.log(this);  // this = global (function call)
    }
    inner();
  }
};

user.greet();  // this inside inner = global (lose context)
</code></pre>
<p>Nested function = lose <code>this</code>.</p>
<h3>Arrow Function</h3>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  
  greet() {
    const inner = () =&gt; {
      console.log(this);  // this = user (inherit from greet)
    };
    inner();
  }
};

user.greet();  // this inside inner = user (keep context)
</code></pre>
<p>Arrow function = inherit <code>this</code> from parent scope.</p>
<h3>When Use Arrow vs Regular</h3>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  
  // Regular function = this = user
  greet() {
    console.log(this.name);  // "Alice"
  },
  
  // Arrow function = this inherit from outer
  introduce: () =&gt; {
    console.log(this.name);  // undefined (this = window/global)
  }
};

user.greet();      // "Alice" (use regular function in object)
user.introduce();  // undefined (arrow lose this context)
</code></pre>
<p>Rule:</p>
<ul>
<li><strong>Object method</strong> = use regular function (get <code>this</code> = object)</li>
<li><strong>Nested callback</strong> = use arrow function (inherit <code>this</code>)</li>
</ul>
<h3>Practical Example</h3>
<pre><code class="language-javascript">const button = {
  label: 'Click me',
  
  // ✗ Wrong - regular function lose this
  setupWrong() {
    document.getElementById('btn').addEventListener('click', function() {
      console.log(this.label);  // this = button element (wrong)
                                // not this button object
    });
  },
  
  // ✓ Right - arrow function keep this
  setupRight() {
    document.getElementById('btn').addEventListener('click', () =&gt; {
      console.log(this.label);  // this = button object (right)
                                // inherited from setupRight
    });
  }
};
</code></pre>
<p>Event listener = arrow function keep <code>this</code>.</p>
<hr />
<h2>Common this Mistakes</h2>
<h3>Mistake 1: Losing this in Callback</h3>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  
  loadData(callback) {
    setTimeout(callback, 1000);
  },
  
  fetch() {
    this.loadData(function() {
      console.log(this.name);  // this = undefined (function call)
    });
  }
};

user.fetch();  // undefined (wrong)
</code></pre>
<p>Fix with arrow function:</p>
<pre><code class="language-javascript">user.fetch() {
  this.loadData(() =&gt; {
    console.log(this.name);  // this = user (right)
  });
}
</code></pre>
<h3>Mistake 2: Extracting Method Without Context</h3>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  greet() {
    console.log(this.name);
  }
};

const greet = user.greet;  // Extract method
greet();  // undefined (lose this)
</code></pre>
<p>Fix with .bind():</p>
<pre><code class="language-javascript">const greet = user.greet.bind(user);  // Keep this = user
greet();  // "Alice" (right)
</code></pre>
<p><code>.bind()</code> = permanently set <code>this</code>.</p>
<h3>Mistake 3: Confusing this in Constructor</h3>
<pre><code class="language-javascript">function User(name) {
  this.name = name;
  
  this.greet = function() {
    console.log(this.name);  // this = user instance
  };
}

const user = new User('Alice');
user.greet();  // "Alice" (this = user)
</code></pre>
<p><code>new</code> = call function as constructor = <code>this</code> = new instance.</p>
<h3>Mistake 4: this in Arrow Function at Object Level</h3>
<pre><code class="language-javascript">// ✗ Wrong - arrow function at object level
const user = {
  name: 'Alice',
  
  greet: () =&gt; {
    console.log(this.name);  // this = window/global
                             // not user object
  }
};

user.greet();  // undefined (wrong)

// ✓ Right - regular function
const user = {
  name: 'Alice',
  
  greet() {
    console.log(this.name);  // this = user
  }
};

user.greet();  // "Alice" (right)
</code></pre>
<p>Object method = use regular function. Not arrow function.</p>
<h3>Mistake 5: Assuming this Same in Nested Function</h3>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  
  process() {
    console.log(this.name);  // "Alice" (this = user)
    
    function inner() {
      console.log(this.name);  // undefined (this = global)
    }
    
    inner();  // this change!
  }
};

user.process();  // "Alice" then undefined
</code></pre>
<p>Nested function = new context = <code>this</code> change.</p>
<hr />
<h2>Methods to Control this</h2>
<h3>1. Using .call()</h3>
<p>Call function with specific <code>this</code>.</p>
<pre><code class="language-javascript">function greet(greeting) {
  console.log(`\({greeting}, I'm \){this.name}`);
}

const user = { name: 'Alice' };

greet.call(user, 'Hi');  // "Hi, I'm Alice"
                         // this = user
</code></pre>
<p><code>.call(thisArg, arg1, arg2, ...)</code> = set <code>this</code> and call.</p>
<h3>2. Using .apply()</h3>
<p>Like <code>.call()</code> but arguments as array.</p>
<pre><code class="language-javascript">function greet(greeting, emoji) {
  console.log(`\({greeting}, I'm \){this.name} ${emoji}`);
}

const user = { name: 'Alice' };

greet.apply(user, ['Hi', '👋']);  // "Hi, I'm Alice 👋"
                                   // this = user
</code></pre>
<p><code>.apply(thisArg, [args])</code> = same as call, but array arguments.</p>
<h3>3. Using .bind()</h3>
<p>Create new function with locked <code>this</code>.</p>
<pre><code class="language-javascript">function greet() {
  console.log(`Hi, ${this.name}`);
}

const user = { name: 'Alice' };

const boundGreet = greet.bind(user);  // Create new function

boundGreet();  // "Hi, Alice"
               // this permanently = user
</code></pre>
<p><code>.bind()</code> = don't call immediately. Return new function.</p>
<p><code>.call()</code> and <code>.apply()</code> = call immediately.
<code>.bind()</code> = return function, call later.</p>
<h3>Practical Use: Event Listener</h3>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  
  setupButton() {
    const button = document.getElementById('btn');
    
    // ✗ Lose this
    // button.addEventListener('click', this.onClick);
    
    // ✓ Keep this
    button.addEventListener('click', this.onClick.bind(this));
  },
  
  onClick() {
    console.log(`Clicked by ${this.name}`);
  }
};
</code></pre>
<p><code>.bind(this)</code> = keep <code>this</code> in event listener.</p>
<hr />
<h2>this in Different Contexts</h2>
<h3>Global Scope</h3>
<pre><code class="language-javascript">console.log(this);  // Browser: window, Node.js: depends on module
</code></pre>
<h3>Inside Object Method</h3>
<pre><code class="language-javascript">const obj = {
  method() {
    console.log(this);  // this = obj
  }
};

obj.method();
</code></pre>
<h3>Inside Regular Function</h3>
<pre><code class="language-javascript">function func() {
  console.log(this);  // undefined (strict) or global (non-strict)
}

func();
</code></pre>
<h3>Inside Arrow Function</h3>
<pre><code class="language-javascript">const arrow = () =&gt; {
  console.log(this);  // this = outer scope's this
};
</code></pre>
<h3>Inside Constructor</h3>
<pre><code class="language-javascript">function Constructor() {
  console.log(this);  // this = new instance
}

new Constructor();
</code></pre>
<h3>Inside Class</h3>
<pre><code class="language-javascript">class MyClass {
  method() {
    console.log(this);  // this = instance
  }
}

const obj = new MyClass();
obj.method();
</code></pre>
<h3>Inside Class Arrow Method</h3>
<pre><code class="language-javascript">class MyClass {
  method = () =&gt; {
    console.log(this);  // this = instance (arrow method)
  }
}
</code></pre>
<hr />
<h2>Practical Examples</h2>
<h3>Example 1: User Object</h3>
<pre><code class="language-javascript">const user = {
  name: 'Alice',
  age: 25,
  
  greet() {
    console.log(`Hello, I'm ${this.name}`);
  },
  
  birthday() {
    this.age++;
    console.log(`Happy birthday! Now ${this.age}`);
  },
  
  describe() {
    return `\({this.name} is \){this.age} years old`;
  }
};

user.greet();      // "Hello, I'm Alice"
user.birthday();   // "Happy birthday! Now 26"
console.log(user.describe());  // "Alice is 26 years old"

// All use this = user
</code></pre>
<h3>Example 2: Button Handler</h3>
<pre><code class="language-javascript">const app = {
  count: 0,
  
  init() {
    document.getElementById('btn').addEventListener(
      'click',
      this.handleClick.bind(this)  // Keep this = app
    );
  },
  
  handleClick() {
    this.count++;
    console.log(`Clicked ${this.count} times`);
  }
};

app.init();
// Click button → "Clicked 1 times"
// Click button → "Clicked 2 times"
</code></pre>
<p>Without <code>.bind(this)</code> = this = button element (wrong).</p>
<h3>Example 3: Method Borrowing</h3>
<pre><code class="language-javascript">const user1 = { name: 'Alice' };
const user2 = { name: 'Bob' };

function greet() {
  console.log(`Hi, ${this.name}`);
}

greet.call(user1);   // "Hi, Alice"
greet.call(user2);   // "Hi, Bob"

// Same function, different this, different output
</code></pre>
<p>Use <code>.call()</code> to borrow function with different context.</p>
<h3>Example 4: Constructor Pattern</h3>
<pre><code class="language-javascript">function User(name, age) {
  this.name = name;
  this.age = age;
  
  this.greet = function() {
    console.log(`I'm ${this.name}`);
  };
}

const user1 = new User('Alice', 25);
const user2 = new User('Bob', 30);

user1.greet();  // "I'm Alice" (this = user1)
user2.greet();  // "I'm Bob"   (this = user2)
</code></pre>
<p><code>new</code> = create instance, set <code>this</code> = instance.</p>
<h3>Example 5: React Class Component</h3>
<pre><code class="language-javascript">class Counter extends React.Component {
  constructor() {
    super();
    this.state = { count: 0 };
    
    // Bind to keep this = component
    this.handleClick = this.handleClick.bind(this);
  }
  
  handleClick() {
    this.setState({ count: this.state.count + 1 });
  }
  
  render() {
    return &lt;button onClick={this.handleClick}&gt;Count: {this.state.count}&lt;/button&gt;;
  }
}
</code></pre>
<p>React = need bind or arrow function to keep <code>this</code>.</p>
<hr />
<h2>this Cheat Sheet</h2>
<pre><code>WHO CALL IT?           this = WHAT?
═════════════════      ══════════════════════
obj.method()           obj (the caller object)

func()                 undefined (strict) or global (non-strict)

new Constructor()      new instance

func.call(obj)         obj (explicitly set)

func.bind(obj)()       obj (locked in new function)

inside arrow function  outer scope's this (inherit)

inside event           element (default) or bound object
listener

inside setTimeout()    global (unless arrow)
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Object methods:</strong></p>
<pre><code class="language-javascript">// Create user object with:
// - name, email properties
// - greet() method (use this.name)
// - getEmail() method (use this.email)
// Test each method
</code></pre>
<p><strong>2. Losing and finding this:</strong></p>
<pre><code class="language-javascript">// Create object with method
// Extract method, call it (lose this)
// Fix using .bind()
// Verify this = object again
</code></pre>
<p><strong>3. Arrow vs regular:</strong></p>
<pre><code class="language-javascript">// Create object method that:
// - Use regular function for this = object
// - Use arrow function inside (inherit this)
// Test both work correctly
</code></pre>
<p><strong>4. Event listener:</strong></p>
<pre><code class="language-javascript">// Create button handler object
// Add click listener
// Use .bind(this) to keep context
// Verify this = object inside handler
</code></pre>
<p><strong>5. Constructor pattern:</strong></p>
<pre><code class="language-javascript">// Create User constructor function
// Add method using this.name
// Create 2 instances
// Call method on each (different this each time)
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong><code>this</code></strong> = reference to caller. Who call function? That who <code>this</code> is.</p>
</li>
<li><p><strong>Global context</strong> = <code>this</code> = window (browser) or global (Node.js).</p>
</li>
<li><p><strong>Inside object method</strong> = <code>this</code> = object calling method.</p>
</li>
<li><p><strong>Inside function (not method)</strong> = <code>this</code> = global or undefined (strict).</p>
</li>
<li><p><strong>Caller determine <code>this</code></strong> = same function, different caller, different <code>this</code>.</p>
</li>
<li><p><strong>Arrow function</strong> = inherit <code>this</code> from outer scope (don't create own).</p>
</li>
<li><p><strong>Regular function</strong> = create own <code>this</code> (depend on caller).</p>
</li>
<li><p><strong><code>.call(obj)</code></strong> = call function with <code>this</code> = obj (immediately).</p>
</li>
<li><p><strong><code>.apply(obj, [args])</code></strong> = like call but arguments as array (immediately).</p>
</li>
<li><p><strong><code>.bind(obj)</code></strong> = create new function with <code>this</code> = obj (not immediate).</p>
</li>
<li><p><strong>Nested function</strong> = lose <code>this</code>. Use arrow function or <code>.bind()</code>.</p>
</li>
<li><p><strong>Object method</strong> = use regular function (get <code>this</code> = object).</p>
</li>
<li><p><strong>Event listener</strong> = use arrow or <code>.bind()</code> to keep <code>this</code>.</p>
</li>
<li><p><strong>Constructor</strong> = <code>new</code> set <code>this</code> = new instance.</p>
</li>
<li><p><strong>Class method</strong> = <code>this</code> = instance automatically.</p>
</li>
<li><p><strong>Arrow in object</strong> = wrong. Lose <code>this</code> context.</p>
</li>
<li><p><strong>Remember</strong> = <code>this</code> = who calling the function.</p>
</li>
</ul>
<p>Master <code>this</code> = master JavaScript.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[The Node.js Event Loop ]]></title><description><![CDATA[Node.js run single thread. But handle thousands requests. How? Event loop. Event loop = manager that decide what code run when. Without it, Node.js freeze on first slow task.
This about understanding ]]></description><link>https://blog.harshx.in/the-node-js-event-loop</link><guid isPermaLink="true">https://blog.harshx.in/the-node-js-event-loop</guid><category><![CDATA[Node.js]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 12:23:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/74fa92c5-1cfc-4ce6-9986-6e216433de48.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Node.js run single thread. But handle thousands requests. How? Event loop. Event loop = manager that decide what code run when. Without it, Node.js freeze on first slow task.</p>
<p>This about understanding event loop and how it make Node.js fast.</p>
<hr />
<h2>What The Event Loop Is</h2>
<p>Event loop = forever-running manager. Check what task ready, run it, repeat.</p>
<h3>Simple Definition</h3>
<p>Event loop = system that manage code execution. When one task finish, event loop grab next task. One at time, but very fast.</p>
<h3>Real Analogy</h3>
<p>Coffee shop barista:</p>
<pre><code>Barista job = event loop

1. Customer 1 order coffee
   → Add to task queue

2. Customer 2 order coffee
   → Add to task queue

3. Customer 1 order ready
   → Grab from queue, serve customer 1

4. Customer 3 order
   → Add to task queue

5. Customer 2 order ready
   → Grab from queue, serve customer 2

Barista work one task at time.
But move very fast. Seem like doing all at once.
</code></pre>
<p>Event loop = barista. Task queue = order list. Node.js = coffee shop.</p>
<h3>Single Thread Problem</h3>
<p>Node.js run on single thread. One piece code run at time.</p>
<pre><code>Normal language (blocking):
  User 1 request → Server busy (10 seconds)
                 → User 2 wait
                 → User 3 wait
                 → User 100 wait
</code></pre>
<p>If use blocking code, other users stuck.</p>
<pre><code>Node.js (event loop):
  User 1 request → Start task, move on
  User 2 request → Start task, move on
  User 3 request → Start task, move on
  User 100 request → Start task, move on
  
  Meanwhile...
  User 1 task done → handle response
  User 2 task done → handle response
  etc.
</code></pre>
<p>Event loop = manage all at once without blocking.</p>
<h3>Why Event Loop Matter</h3>
<p>Without event loop:</p>
<pre><code class="language-javascript">// Code hang forever on slow task
fs.readFileSync('huge-file.txt');  // Block 10 seconds
// Everything wait 10 seconds
</code></pre>
<p>With event loop:</p>
<pre><code class="language-javascript">// Code don't wait
fs.readFile('huge-file.txt', () =&gt; {
  // Run later when file ready
});
// Continue immediately
</code></pre>
<hr />
<h2>Single Thread Limitation</h2>
<p>Node.js only one thread. One line code run at time.</p>
<h3>Thread = What?</h3>
<p>Thread = worker. One thread = one worker.</p>
<p>Normal server:</p>
<pre><code>10 threads → 10 workers → handle 10 users at once
Each user have own thread
</code></pre>
<p>Node.js:</p>
<pre><code>1 thread → 1 worker → handle 1,000 users at once
But very smart worker (event loop)
</code></pre>
<h3>Why Single Thread?</h3>
<p>Advantage:</p>
<ul>
<li>Simple. No complicated multi-thread stuff.</li>
<li>No thread collision (same variable, two threads edit = crash).</li>
<li>Event loop handle many users.</li>
</ul>
<p>Disadvantage:</p>
<ul>
<li>Can't do CPU-heavy work (loop 1 billion times = freeze).</li>
<li>Heavy math block everything.</li>
</ul>
<h3>The Event Loop Solution</h3>
<p>Event loop = cheat. Act like many threads but only one.</p>
<pre><code>Event loop work:

Check call stack: anything running?
  Yes → Let it finish
  No → Check task queue

Task queue have jobs?
  Yes → Grab one, run it
  No → Wait

Repeat forever
</code></pre>
<p>User see many tasks happening. Actually one at time. But so fast, seem parallel.</p>
<hr />
<h2>Call Stack vs Task Queue</h2>
<p>Two place where code live: call stack and task queue.</p>
<h3>Call Stack</h3>
<p>Call stack = where code execute right now.</p>
<pre><code class="language-javascript">function greet() {
  console.log('Hello');
}

function main() {
  greet();  // Call stack: main → greet
}

main();
</code></pre>
<p>Call stack during execution:</p>
<pre><code>Step 1: main() call
  Stack: [main]

Step 2: main call greet()
  Stack: [main, greet]

Step 3: greet run, print "Hello"
  Stack: [main, greet]

Step 4: greet finish
  Stack: [main]

Step 5: main finish
  Stack: []
</code></pre>
<p>Call stack is LIFO (last in, first out). Last function added, first to finish.</p>
<h3>Task Queue</h3>
<p>Task queue = where async tasks wait. They not run yet.</p>
<pre><code class="language-javascript">setTimeout(() =&gt; {
  console.log('Later');
}, 1000);

console.log('Now');
</code></pre>
<p>Execution:</p>
<pre><code>Step 1: Call setTimeout
  → Callback add to task queue (but not run yet)
  → Timer start (1 second)

Step 2: console.log('Now') run
  Print: "Now"

Step 3: 1 second pass
  → Callback in queue, ready

Step 4: Call stack empty
  → Event loop grab from task queue
  → Run callback

Step 5: Print "Later"
</code></pre>
<h3>Call Stack vs Task Queue</h3>
<pre><code>CALL STACK              TASK QUEUE
═════════════════       ════════════════════
Where code run now      Where async wait

LIFO (stack)            FIFO (queue)

Run immediately         Run when stack empty

Normal function         Async callback
console.log             setTimeout
math operation          fs.readFile
                        db.query
</code></pre>
<hr />
<h2>Event Loop Execution Cycle</h2>
<p>Event loop = forever loop. Check → run → check → run.</p>
<h3>Step By Step</h3>
<pre><code>Event Loop Cycle:

1. Check call stack
   → Anything running?
      No → Go to step 2
      Yes → Wait for finish, go to step 2

2. Check task queue
   → Any callback waiting?
      Yes → Grab first callback
            Run it (add to call stack)
            Go to step 1
      No → Go to step 3

3. Check for more callbacks
   → Wait until something in queue
   → Go to step 1

Repeat forever (while Node.js alive)
</code></pre>
<h3>Code Example: Event Loop in Action</h3>
<pre><code class="language-javascript">console.log('1. Start');

setTimeout(() =&gt; {
  console.log('3. Timeout callback');
}, 0);  // Even 0ms, go to queue

console.log('2. End');
</code></pre>
<p>Output:</p>
<pre><code>1. Start
2. End
3. Timeout callback
</code></pre>
<p>Why?</p>
<pre><code>Step 1: console.log('1. Start') run
  Print: "1. Start"
  Call stack: [log]
  
Step 2: setTimeout call
  Callback go to task queue
  Timer (0ms) start immediately
  Call stack: empty

Step 3: console.log('2. End') run
  Print: "2. End"
  Call stack: empty

Step 4: Event loop check
  Call stack: empty
  Task queue: [callback waiting]
  
Step 5: Event loop grab callback from queue
  Run callback (print "3. Timeout callback")

Output:
1. Start
2. End
3. Timeout callback
</code></pre>
<p>Even <code>setTimeout(..., 0)</code> don't run immediately. Callback go to queue. Wait for stack empty.</p>
<h3>Bigger Example</h3>
<pre><code class="language-javascript">console.log('A');

setTimeout(() =&gt; {
  console.log('B');
}, 0);

Promise.resolve()
  .then(() =&gt; {
    console.log('C');
  });

console.log('D');
</code></pre>
<p>Output:</p>
<pre><code>A
D
C
B
</code></pre>
<p>Why?</p>
<pre><code>Execution:
console.log('A')        → Print "A"
setTimeout(...)         → Callback to task queue
Promise.then(...)       → Callback to microtask queue (different queue)
console.log('D')        → Print "D"

Call stack empty. Event loop check queues:

First: Microtask queue (Promise callbacks run first)
  Run callback → Print "C"

Then: Task queue (Timer callbacks run after)
  Run callback → Print "B"
</code></pre>
<p>Node.js have two queues actually:</p>
<ul>
<li><strong>Microtask queue</strong> = Promise, async/await (run first)</li>
<li><strong>Task queue</strong> = setTimeout, setInterval (run second)</li>
</ul>
<p>Not too deep. Just know: Promise callback run before setTimeout callback.</p>
<hr />
<h2>How Async Operations Work</h2>
<p>Async operations use event loop. Start task, don't wait. Later callback fire.</p>
<h3>File Read</h3>
<pre><code class="language-javascript">const fs = require('fs');

console.log('1. Start');

fs.readFile('file.txt', (err, data) =&gt; {
  console.log('3. File read done');
});

console.log('2. Continue');
</code></pre>
<p>Output:</p>
<pre><code>1. Start
2. Continue
3. File read done
</code></pre>
<p>Timeline:</p>
<pre><code>Step 1: fs.readFile call
  → File reading start (background)
  → Callback add to task queue
  → But not run yet

Step 2: Continue immediately
  → Don't wait for file

Step 3: Call stack empty

Step 4: File reading done
  → Callback ready in queue

Step 5: Event loop run callback
  → Print "3. File read done"
</code></pre>
<h3>Database Query</h3>
<pre><code class="language-javascript">const db = require('./db');

console.log('1. Query start');

db.query('SELECT * FROM users', (err, result) =&gt; {
  console.log('3. Query done:', result);
});

console.log('2. Did not wait');
</code></pre>
<p>Same pattern:</p>
<pre><code>1. Query start (print)
2. Did not wait (print)
3. Query done: [...] (print after query finish)
</code></pre>
<p>Query happen background. Event loop run callback when done.</p>
<h3>Multiple Async Operations</h3>
<pre><code class="language-javascript">const fs = require('fs').promises;

console.log('1. Start');

async function loadData() {
  const file1 = await fs.readFile('file1.txt');
  const file2 = await fs.readFile('file2.txt');
  
  console.log('3. Both files loaded');
}

loadData();

console.log('2. Continue');
</code></pre>
<p>Output:</p>
<pre><code>1. Start
2. Continue
3. Both files loaded
</code></pre>
<p>Why "2" before "3"?</p>
<pre><code>Step 1: loadData() call
  → First await (readFile)
  → Callback add to queue
  → Function pause (await)
  → Return immediately

Step 2: Continue (print)
  → Call stack empty

Step 3: File 1 ready
  → First await resolve
  → loadData continue
  → Second await (readFile)
  → Another callback add to queue
  → Function pause again

Step 4: File 2 ready
  → Second await resolve
  → Print "3. Both files loaded"
</code></pre>
<p>Each <code>await</code> pause function. Event loop continue other work. When callback ready, function resume.</p>
<hr />
<h2>Timers vs I/O Callbacks</h2>
<p>Different type async operations. Different timing.</p>
<h3>Timers: setTimeout, setInterval</h3>
<pre><code class="language-javascript">setTimeout(() =&gt; {
  console.log('Timer done');
}, 1000);  // Wait 1000ms
</code></pre>
<p>How it work:</p>
<pre><code>Event loop:

1. setTimeout call
   → Add callback to task queue
   → Timer start 1000ms

2. Event loop continue
   → Do other work

3. 1000ms pass
   → Timer ready
   → Callback can run

4. Call stack empty
   → Event loop grab callback
   → Run it

5. Print "Timer done"
</code></pre>
<p>Timers = time-based. Wait X milliseconds.</p>
<h3>I/O Callbacks: File read, Database</h3>
<pre><code class="language-javascript">fs.readFile('file.txt', () =&gt; {
  console.log('File done');
});
</code></pre>
<p>How it work:</p>
<pre><code>Event loop:

1. fs.readFile call
   → File reading start (OS handle)
   → Callback add to queue (but not ready yet)

2. Event loop continue
   → Do other work

3. OS finish reading file
   → Callback marked ready
   → (Might be 10ms, might be 1 second)

4. Call stack empty
   → Event loop grab callback
   → Run it

5. Print "File done"
</code></pre>
<p>I/O = depends on OS. Could be slow. Could be fast. Event loop not know when.</p>
<h3>Difference</h3>
<pre><code>TIMERS                      I/O
══════════════════          ════════════════════
Known wait time             Unknown wait time
Wait X milliseconds         Wait until OS done

setTimeout(...)             fs.readFile
setInterval(...)            db.query
                            http.get

Useful for delays           Useful for reading
Useful for retry            Useful for querying
</code></pre>
<p>Both use event loop. Both don't block. But different reason when callback fire.</p>
<hr />
<h2>Event Loop and Scalability</h2>
<p>Event loop = why Node.js fast for many users.</p>
<h3>The Problem: Threads</h3>
<p>Traditional server (many threads):</p>
<pre><code>100 users → 100 threads
Each thread = memory
Each thread = overhead

Total memory = high
</code></pre>
<p>Creates 100 threads = slow.
Handle 100 users = fine.
Handle 1000 users = system crash (not enough memory).</p>
<h3>The Solution: Event Loop</h3>
<p>Node.js (one thread, event loop):</p>
<pre><code>1000 users → 1 thread + event loop
Handle first user → task go to queue
Handle second user → task go to queue
Handle third user → task go to queue
...

Event loop manage all at once.
Total memory = low
Handle 1000 users = easy
Handle 10,000 users = still working
</code></pre>
<p>Event loop = memory efficient.</p>
<h3>Why Event Loop Scale Better</h3>
<pre><code>User come:
  Server start async operation
  User task go to queue
  Server immediately free (handle next user)

Meanwhile:
  User 1 operation running (background)
  User 2 operation running (background)
  User 3 operation running (background)
  ...

When operation done:
  Callback fire
  Server send response to user
</code></pre>
<p>Same 1 thread. Same code. But handle many users.</p>
<h3>Example: Real Server Load</h3>
<pre><code class="language-javascript">const express = require('express');
const app = express();

app.get('/user/:id', async (req, res) =&gt; {
  // 1. Start database query
  const user = await db.getUser(req.params.id);
  
  // 2. Query happen background (not blocking)
  
  // 3. When ready, callback fire
  
  // 4. Send response
  res.json(user);
});

app.listen(3000);
</code></pre>
<p>Handle 1000 requests:</p>
<pre><code>Request 1 → Start DB query (background)
Request 2 → Start DB query (background)
Request 3 → Start DB query (background)
...
Request 1000 → Start DB query (background)

All queries run parallel (in background).
Server only use 1 thread.
Memory = low.
Speed = fast.

When Request 1 query done → Send response
When Request 2 query done → Send response
etc.
</code></pre>
<p>Without event loop:</p>
<ul>
<li>Request 1 query (5 seconds)</li>
<li>Request 2 wait</li>
<li>Request 3 wait</li>
<li>... 1000 requests wait</li>
<li>Total time = 5000 seconds (impossible)</li>
</ul>
<p>With event loop:</p>
<ul>
<li>All 1000 queries at same time</li>
<li>Total time = ~5 seconds</li>
</ul>
<p>That why Node.js famous for scaling.</p>
<hr />
<h2>Event Loop Problems (CPU-Heavy Code)</h2>
<p>Event loop great for I/O. Bad for CPU-heavy code.</p>
<h3>Problem: Long Running Code</h3>
<pre><code class="language-javascript">app.get('/calculate', (req, res) =&gt; {
  // CPU heavy - loop 1 billion times
  let sum = 0;
  for (let i = 0; i &lt; 1000000000; i++) {
    sum += i;
  }
  
  res.json({ sum });
});
</code></pre>
<p>What happen:</p>
<pre><code>User 1 request
  → Start calculate loop
  → Block event loop (3 seconds)
  
During those 3 seconds:
  User 2 request (wait)
  User 3 request (wait)
  User 4 request (wait)
  
User 1 response send (3 seconds later)
  → Now User 2 can start
  → Now User 3 can start
</code></pre>
<p>CPU-heavy code = freeze event loop. Other users suffer.</p>
<h3>Solution: Worker Threads</h3>
<p>For heavy work, use worker threads (separate thread):</p>
<pre><code class="language-javascript">const { Worker } = require('worker_threads');

app.get('/calculate', (req, res) =&gt; {
  const worker = new Worker('./calculate.js');
  
  worker.on('message', (result) =&gt; {
    res.json({ sum: result });
  });
});
</code></pre>
<p>Worker thread do heavy work. Main thread (event loop) continue serve other users.</p>
<p>But mostly: avoid CPU-heavy code on server. Use Node.js for I/O, not math.</p>
<hr />
<h2>Event Loop in Real Code</h2>
<h3>Example 1: Simple Request</h3>
<pre><code class="language-javascript">const express = require('express');
const app = express();

app.get('/hello', (req, res) =&gt; {
  console.log('Request come');
  res.json({ message: 'Hello' });
});

app.listen(3000);
</code></pre>
<p>Timeline:</p>
<pre><code>User 1 request come
  → /hello route handler run
  → Print "Request come"
  → Send response
  → Handler finish (remove from stack)

User 2 request come
  → /hello route handler run
  → Print "Request come"
  → Send response
  → Handler finish

Event loop continue... always
</code></pre>
<p>Each request = separate handler. Event loop run one, then next.</p>
<h3>Example 2: Database Request</h3>
<pre><code class="language-javascript">const express = require('express');
const app = express();

app.get('/user/:id', async (req, res) =&gt; {
  console.log('1. Query start');
  
  const user = await db.query('SELECT * FROM users WHERE id = ?', [req.params.id]);
  
  console.log('2. Query done');
  res.json(user);
});

app.listen(3000);
</code></pre>
<p>Timeline:</p>
<pre><code>User 1 request
  → Print "1. Query start"
  → await (pause here)
  → Query add to queue
  → Handler pause

User 2 request (meanwhile)
  → Print "1. Query start"
  → await (pause here)
  → Query add to queue
  → Handler pause

User 1 query done
  → Callback fire
  → Print "2. Query done"
  → Send response

User 2 query done
  → Callback fire
  → Print "2. Query done"
  → Send response
</code></pre>
<p>Both queries happen at same time. Event loop manage both.</p>
<h3>Example 3: File Operations</h3>
<pre><code class="language-javascript">const fs = require('fs').promises;

async function processFiles() {
  console.log('1. Start');
  
  const files = await Promise.all([
    fs.readFile('file1.txt'),
    fs.readFile('file2.txt'),
    fs.readFile('file3.txt')
  ]);
  
  console.log('2. All done');
}

processFiles();
console.log('3. Continue');
</code></pre>
<p>Output:</p>
<pre><code>1. Start
3. Continue
2. All done
</code></pre>
<p>Timeline:</p>
<pre><code>processFiles() call
  → Print "1. Start"
  → Promise.all start all 3 reads
  → await (pause function)

Print "3. Continue"
  → Main code continue

File reads happen background:
  OS read file 1
  OS read file 2
  OS read file 3

All 3 files done
  → Promise.all resolve
  → Function resume
  → Print "2. All done"
</code></pre>
<p>One thread. Three file reads at same time. Event loop magic.</p>
<hr />
<h2>Event Loop Visualization</h2>
<h3>Step-by-Step Flow</h3>
<pre><code>START
  │
  ├─→ Check Call Stack
  │   │
  │   ├─ Something running?
  │   │  Yes → Wait for finish
  │   │  No → Go to next
  │   │
  │
  ├─→ Check Microtask Queue (Promise)
  │   │
  │   ├─ Anything waiting?
  │   │  Yes → Run it, go back to stack check
  │   │  No → Go to next
  │   │
  │
  ├─→ Check Task Queue (setTimeout, I/O)
  │   │
  │   ├─ Anything waiting?
  │   │  Yes → Run it, go back to stack check
  │   │  No → Sleep until something arrive
  │   │
  │
  └─→ Loop again (forever)
</code></pre>
<h3>Code Execution Order</h3>
<pre><code class="language-javascript">// What print first?

console.log('A');                    // Call stack run

setTimeout(() =&gt; {
  console.log('B');                  // Task queue (timer)
}, 0);

Promise.resolve().then(() =&gt; {
  console.log('C');                  // Microtask queue (Promise)
});

console.log('D');                    // Call stack run
</code></pre>
<p>Order:</p>
<pre><code>1. A, D (Call stack, synchronous code)
2. C    (Microtask queue, Promises)
3. B    (Task queue, Timers)

Output:
A
D
C
B
</code></pre>
<p>Event loop priority:</p>
<ol>
<li>Synchronous code (call stack)</li>
<li>Promises/async (microtask queue)</li>
<li>Timers/I/O (task queue)</li>
</ol>
<hr />
<h2>Common Event Loop Mistakes</h2>
<h3>Mistake 1: Think Await Block Other Users</h3>
<pre><code class="language-javascript">// ✗ Think this block other users
app.get('/user/:id', async (req, res) =&gt; {
  const user = await db.getUser(id);  // Blocking?
  res.json(user);
});

// ✓ Reality: don't block others
// await pause THIS function
// But event loop continue handle OTHER users
</code></pre>
<p>Each user have own context. Await pause one context, not all.</p>
<h3>Mistake 2: Forget Event Loop on CPU Work</h3>
<pre><code class="language-javascript">// ✗ Block event loop (bad for other users)
for (let i = 0; i &lt; 1000000000; i++) {
  sum += i;  // CPU heavy
}

// ✓ Use worker thread or break into chunks
const chunk = async () =&gt; {
  sum += i;
  // resume later
};
</code></pre>
<p>CPU work can't use async. Must use worker threads or split work.</p>
<h3>Mistake 3: Assume setTimeout(0) = Immediate</h3>
<pre><code class="language-javascript">// ✗ Think callback run immediately
setTimeout(() =&gt; {
  console.log('Immediate?');
}, 0);

// ✓ Reality: callback wait in queue
// Go to task queue
// Run when stack empty
// NOT immediately
</code></pre>
<p>Even 0ms don't mean immediately. Go to queue. Might wait milliseconds.</p>
<h3>Mistake 4: Not Understand Microtask Queue</h3>
<pre><code class="language-javascript">// ✗ Think Promise and setTimeout same
console.log('A');

setTimeout(() =&gt; console.log('B'), 0);
Promise.resolve().then(() =&gt; console.log('C'));

console.log('D');

// ✗ Expect: A, B, C, D
// ✓ Real: A, D, C, B
</code></pre>
<p>Promise use microtask queue (run first).
setTimeout use task queue (run second).</p>
<p>Different queues = different timing.</p>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Event loop order:</strong></p>
<pre><code class="language-javascript">// Predict output order
console.log('1');

setTimeout(() =&gt; console.log('2'), 0);

Promise.resolve()
  .then(() =&gt; console.log('3'))
  .then(() =&gt; console.log('4'));

console.log('5');

// What order? Why?
// Test and verify
</code></pre>
<p><strong>2. Async operations:</strong></p>
<pre><code class="language-javascript">// Write function that:
// - Read 3 files
// - Do all 3 at same time (parallel)
// - Print results when all done
// Use Promise.all or async/await
</code></pre>
<p><strong>3. Understand blocking:</strong></p>
<pre><code class="language-javascript">// Create two endpoints:
// - One with CPU loop (block)
// - One without block

// Test: which handle user faster?
// Monitor: does one slow down other?
</code></pre>
<p><strong>4. Event loop trace:</strong></p>
<pre><code class="language-javascript">// Trace execution step by step

app.get('/test', async (req, res) =&gt; {
  console.log('A');
  
  const file = await fs.readFile('file.txt');
  
  console.log('B');
  res.json(file);
});

// When do A and B print?
// What if 3 users request at same time?
</code></pre>
<p><strong>5. Fix scalability:</strong></p>
<pre><code class="language-javascript">// Given slow endpoint
// Rewrite to use event loop better
// Should handle 1000 users, not 10

// Before: server crash with 1000 users
// After: server handle 1000 users easy
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Event loop</strong> = manager. Check what ready, run it, repeat.</p>
</li>
<li><p><strong>Single thread</strong> = one code run at time. But event loop make seem parallel.</p>
</li>
<li><p><strong>Call stack</strong> = where code run now. LIFO order.</p>
</li>
<li><p><strong>Task queue</strong> = where async callback wait. FIFO order.</p>
</li>
<li><p><strong>Event loop cycle</strong>: Check stack → Check queue → Run task → Repeat.</p>
</li>
<li><p><strong>Async operations</strong> = start, don't wait. Callback fire later.</p>
</li>
<li><p><strong>Microtask queue</strong> = Promise callbacks. Run before task queue.</p>
</li>
<li><p><strong>Task queue</strong> = setTimeout, I/O callbacks. Run after microtask.</p>
</li>
<li><p><strong>Timers</strong> = time-based. Wait X milliseconds.</p>
</li>
<li><p><strong>I/O callbacks</strong> = depends on OS. When file/DB ready.</p>
</li>
<li><p><strong>Scalability</strong> = event loop handle many users with 1 thread.</p>
</li>
<li><p><strong>No threads needed</strong> = event loop do work of many threads.</p>
</li>
<li><p><strong>Memory efficient</strong> = 1 thread vs 100 threads.</p>
</li>
<li><p><strong>CPU-heavy code</strong> = freeze event loop. Use worker threads.</p>
</li>
<li><p><strong>Await pause function</strong> = not block event loop. Other users continue.</p>
</li>
<li><p><strong>setTimeout(0) != immediate</strong> = go to task queue. Wait until stack empty.</p>
</li>
<li><p><strong>Promise run first</strong> = microtask queue before task queue.</p>
</li>
<li><p><strong>Without event loop</strong> = Node.js can't scale. Dead project.</p>
</li>
<li><p><strong>With event loop</strong> = 1000 users, 1 thread. That magic.</p>
</li>
</ul>
<p>Event loop = why Node.js exist. Without it, just another server language.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Blocking vs Non-Blocking Code in Node.js]]></title><description><![CDATA[Node.js runs on single thread. Blocking code freezes whole server. Non-blocking code keep server alive. Difference = slow API vs fast API.
This about blocking, non-blocking, and async patterns in Node]]></description><link>https://blog.harshx.in/blocking-vs-non-blocking-code-in-node-js</link><guid isPermaLink="true">https://blog.harshx.in/blocking-vs-non-blocking-code-in-node-js</guid><category><![CDATA[Node.js]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 12:15:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/b5fc65d8-7c1d-4e78-af82-59c2444b6282.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Node.js runs on single thread. Blocking code freezes whole server. Non-blocking code keep server alive. Difference = slow API vs fast API.</p>
<p>This about blocking, non-blocking, and async patterns in Node.js.</p>
<hr />
<h2>What Blocking Code Means</h2>
<p>Blocking = waiting. Code wait for operation finish before continue.</p>
<h3>Simple Definition</h3>
<p>Blocking code pause execution until task complete. Nothing else happen. Like stuck in line at store.</p>
<h3>Real Analogy</h3>
<p>Restaurant waiter without non-blocking:</p>
<pre><code>Waiter take order from customer 1.
Wait for kitchen finish cooking.
[Stand there 10 minutes doing nothing]
[Customer 2 wait, customer 3 wait, customer 4 wait]
Finally food ready.
Waiter bring food to customer 1.
NOW waiter take order from customer 2.
</code></pre>
<p>Bad service. Customers angry. Waiter waste time.</p>
<h3>The Problem</h3>
<pre><code class="language-javascript">// Blocking code
const fs = require('fs');

console.log('Start reading file');
const data = fs.readFileSync('large-file.txt');  // BLOCK HERE
console.log('File read complete');
console.log(data);
</code></pre>
<p>What happen:</p>
<pre><code>1. Server start
2. Start reading file [WAIT]
3. [WAIT] [WAIT] [WAIT]   &lt;- Nothing happen for 5 seconds
4. File finally loaded
5. Print data
6. During step 3, if 100 users try access server, ALL wait
</code></pre>
<h3>Why Blocking Kill Servers</h3>
<p>One user read file = 5 seconds.
10 users read file = 50 seconds wait for user 10.
100 users? Server dead.</p>
<hr />
<h2>What Non-Blocking Code Means</h2>
<p>Non-blocking = don't wait. Code start task, move on. When task done, callback fire.</p>
<h3>Simple Definition</h3>
<p>Non-blocking code start operation and continue. Task happen background. When done, callback tell code.</p>
<h3>Real Analogy</h3>
<p>Restaurant waiter WITH non-blocking:</p>
<pre><code>Waiter take order from customer 1.
Send order to kitchen.
[Keep going - don't wait]
Waiter take order from customer 2.
Waiter take order from customer 3.
Kitchen finish customer 1 food.
Waiter bring food.
[Meanwhile take order from customer 4]
Kitchen finish customer 2 food.
Waiter bring food.
</code></pre>
<p>Good service. Customers happy. Waiter busy but move fast.</p>
<h3>Code Example</h3>
<pre><code class="language-javascript">// Non-blocking code
const fs = require('fs');

console.log('Start reading file');

fs.readFile('large-file.txt', (err, data) =&gt; {
  // This callback run LATER when file ready
  console.log('File read complete');
  console.log(data);
});

console.log('Request sent, moving on');
</code></pre>
<p>What happen:</p>
<pre><code>1. Server start
2. Start reading file (DON'T WAIT)
3. Move to next line immediately
4. "Request sent, moving on" print
5. File load in background
6. When ready, callback fire
7. Print data
</code></pre>
<p>During file read, server handle other users.</p>
<hr />
<h2>Why Blocking Slow Servers Down</h2>
<h3>Timeline Comparison</h3>
<p><strong>Blocking (synchronous):</strong></p>
<pre><code>Time (seconds)
0s   ├─ User 1 come
     ├─ Read file [BLOCK]
5s   ├─ File done
     ├─ User 2 come [wait in line]
     ├─ Read file [BLOCK]
10s  ├─ File done
     ├─ User 3 come [wait in line]
     ├─ Read file [BLOCK]
15s  └─ File done

Total time for 3 users = 15 seconds
</code></pre>
<p><strong>Non-blocking (asynchronous):</strong></p>
<pre><code>Time (seconds)
0s   ├─ User 1 come
     ├─ Start read file (don't wait)
0s   ├─ User 2 come
     ├─ Start read file (don't wait)
0s   ├─ User 3 come
     ├─ Start read file (don't wait)
5s   └─ All 3 files ready, return data to users

Total time for 3 users = 5 seconds
</code></pre>
<h3>Real Impact</h3>
<p>With blocking:</p>
<ul>
<li>100 users = 500 seconds (8+ minutes)</li>
<li>Server crash or hang</li>
</ul>
<p>With non-blocking:</p>
<ul>
<li>100 users = 5 seconds</li>
<li>Server smooth</li>
</ul>
<h3>Code Proof</h3>
<pre><code class="language-javascript">// BLOCKING - slow
const fs = require('fs');
console.time('Blocking');

for (let i = 0; i &lt; 3; i++) {
  const data = fs.readFileSync('file.txt');  // Wait each time
  console.log(`Read ${i}`);
}

console.timeEnd('Blocking');
// Blocking: 3000ms (each file take ~1 second)
</code></pre>
<pre><code class="language-javascript">// NON-BLOCKING - fast
const fs = require('fs');
console.time('NonBlocking');

for (let i = 0; i &lt; 3; i++) {
  fs.readFile('file.txt', (err, data) =&gt; {
    console.log(`Read ${i}`);
  });
}

console.timeEnd('NonBlocking');
// NonBlocking: 10ms (all start at once)
</code></pre>
<hr />
<h2>Async Operations in Node.js</h2>
<p>Node.js have many built-in async functions. Don't use Sync version in production.</p>
<h3>File Operations</h3>
<p><strong>Blocking (bad):</strong></p>
<pre><code class="language-javascript">const fs = require('fs');

const data = fs.readFileSync('users.json');  // DON'T DO THIS
console.log(data);
</code></pre>
<p><strong>Non-blocking (good):</strong></p>
<pre><code class="language-javascript">const fs = require('fs');

fs.readFile('users.json', (err, data) =&gt; {
  if (err) {
    console.error('File error:', err);
    return;
  }
  console.log(data);
});
</code></pre>
<h3>Database Calls</h3>
<p><strong>Blocking (bad):</strong></p>
<pre><code class="language-javascript">// Fake sync DB call (most real DB have this)
const user = db.getUserSync(1);  // Block waiting for DB
console.log(user);
</code></pre>
<p><strong>Non-blocking (good):</strong></p>
<pre><code class="language-javascript">// Real async DB call
db.getUser(1, (err, user) =&gt; {
  if (err) {
    console.error('DB error:', err);
    return;
  }
  console.log(user);
});
</code></pre>
<h3>Network Requests</h3>
<p><strong>Blocking (impossible, no sync version):</strong></p>
<pre><code class="language-javascript">// This don't exist - network always async
const response = http.requestSync(url);  // Doesn't exist
</code></pre>
<p><strong>Non-blocking (only way):</strong></p>
<pre><code class="language-javascript">const http = require('http');

http.get(url, (res) =&gt; {
  let data = '';
  res.on('data', (chunk) =&gt; {
    data += chunk;
  });
  res.on('end', () =&gt; {
    console.log(data);
  });
});
</code></pre>
<hr />
<h2>Callbacks: Simple Non-Blocking Pattern</h2>
<p>Callback = function that run later.</p>
<h3>What is Callback?</h3>
<p>Callback = tell Node.js "When done, run this function".</p>
<pre><code class="language-javascript">fs.readFile('file.txt', (err, data) =&gt; {
  // This function run LATER when file ready
  console.log(data);
});
</code></pre>
<p>Function <code>(err, data) =&gt; { ... }</code> = callback.</p>
<h3>Callback Pattern</h3>
<pre><code class="language-javascript">function readUserFile(callback) {
  fs.readFile('user.json', (err, data) =&gt; {
    if (err) {
      callback(err);  // Pass error to callback
      return;
    }
    callback(null, data);  // Pass data to callback
  });
}

// Use it
readUserFile((err, data) =&gt; {
  if (err) {
    console.error('Error:', err);
  } else {
    console.log('User:', data);
  }
});
</code></pre>
<h3>Callback Hell (Problem)</h3>
<p>Nested callbacks get messy:</p>
<pre><code class="language-javascript">fs.readFile('users.json', (err, users) =&gt; {
  if (err) console.error(err);
  
  fs.readFile('posts.json', (err, posts) =&gt; {
    if (err) console.error(err);
    
    fs.readFile('comments.json', (err, comments) =&gt; {
      if (err) console.error(err);
      
      console.log(users, posts, comments);
      // Deep nesting = hard to read
    });
  });
});
</code></pre>
<p>Solution = use Promises or async/await.</p>
<hr />
<h2>Promises: Better Non-Blocking Pattern</h2>
<p>Promise = cleaner callback. Chain operations.</p>
<h3>What is Promise?</h3>
<p>Promise = object that represent future value.</p>
<pre><code class="language-javascript">const promise = fs.promises.readFile('file.txt');

promise
  .then((data) =&gt; {
    console.log('File read:', data);
  })
  .catch((err) =&gt; {
    console.error('Error:', err);
  });
</code></pre>
<h3>Promise Chain</h3>
<p>No nesting needed:</p>
<pre><code class="language-javascript">const fs = require('fs').promises;

fs.readFile('users.json')
  .then((users) =&gt; {
    console.log('Users loaded');
    return fs.readFile('posts.json');  // Chain next operation
  })
  .then((posts) =&gt; {
    console.log('Posts loaded');
    return fs.readFile('comments.json');
  })
  .then((comments) =&gt; {
    console.log('Comments loaded');
    console.log('All data ready');
  })
  .catch((err) =&gt; {
    console.error('Error:', err);
  });
</code></pre>
<p>Clean. Easy read.</p>
<h3>Promise Syntax</h3>
<pre><code class="language-javascript">new Promise((resolve, reject) =&gt; {
  // Do async work
  if (success) {
    resolve(data);  // Pass data when done
  } else {
    reject(error);  // Pass error if fail
  }
});
</code></pre>
<p>Example:</p>
<pre><code class="language-javascript">function readFile(filename) {
  return new Promise((resolve, reject) =&gt; {
    fs.readFile(filename, (err, data) =&gt; {
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    });
  });
}

readFile('users.json')
  .then((data) =&gt; console.log(data))
  .catch((err) =&gt; console.error(err));
</code></pre>
<hr />
<h2>Async/Await: Cleanest Non-Blocking Pattern</h2>
<p>Async/await = write async code like sync code.</p>
<h3>What is Async/Await?</h3>
<p>Async/await = Promises but easier read. Look like normal code.</p>
<pre><code class="language-javascript">async function loadData() {
  try {
    const users = await fs.promises.readFile('users.json');
    console.log('Users:', users);
    
    const posts = await fs.promises.readFile('posts.json');
    console.log('Posts:', posts);
    
  } catch (err) {
    console.error('Error:', err);
  }
}

loadData();
</code></pre>
<p>No <code>.then()</code> chains. Clean.</p>
<h3>Async Function</h3>
<p><code>async</code> keyword make function return Promise:</p>
<pre><code class="language-javascript">async function getData() {
  return 'some data';  // Auto wrapped in Promise
}

getData().then((data) =&gt; console.log(data));  // Work with Promise
</code></pre>
<h3>Await Keyword</h3>
<p><code>await</code> pause function until Promise resolve:</p>
<pre><code class="language-javascript">async function loadFile() {
  console.log('Start');
  
  const data = await fs.promises.readFile('file.txt');
  // Wait here until file ready
  // Then continue
  
  console.log('Done');
  console.log(data);
}

loadFile();
</code></pre>
<p>Timeline:</p>
<pre><code>1. Start (print)
2. Begin reading file
3. PAUSE (await wait)
4. File ready
5. Resume
6. Done (print)
7. Print data
</code></pre>
<h3>Real Example: Async/Await</h3>
<pre><code class="language-javascript">const express = require('express');
const fs = require('fs').promises;
const app = express();

app.get('/users/:id', async (req, res) =&gt; {
  try {
    const userId = req.params.id;
    
    // Read user file
    const userFile = await fs.readFile(`users/${userId}.json`);
    const user = JSON.parse(userFile);
    
    // Read user posts
    const postsFile = await fs.readFile(`posts/${userId}.json`);
    const posts = JSON.parse(postsFile);
    
    // Return both
    res.json({ user, posts });
    
  } catch (err) {
    res.status(500).json({ error: 'Server error' });
  }
});

app.listen(3000);
</code></pre>
<p>During <code>await</code>, server handle other users. Not blocked.</p>
<hr />
<h2>Blocking vs Non-Blocking: Side-by-Side</h2>
<h3>File Read Comparison</h3>
<p><strong>Blocking:</strong></p>
<pre><code class="language-javascript">const fs = require('fs');

function readUser() {
  // This freeze whole server
  const data = fs.readFileSync('user.json');
  return data;
}

const user = readUser();
console.log(user);
</code></pre>
<p><strong>Non-blocking (Promise):</strong></p>
<pre><code class="language-javascript">const fs = require('fs').promises;

function readUser() {
  // Return Promise
  return fs.readFile('user.json');
}

readUser()
  .then((data) =&gt; console.log(data))
  .catch((err) =&gt; console.error(err));
</code></pre>
<p><strong>Non-blocking (Async/Await):</strong></p>
<pre><code class="language-javascript">const fs = require('fs').promises;

async function readUser() {
  try {
    const data = await fs.readFile('user.json');
    return data;
  } catch (err) {
    console.error(err);
  }
}

const user = await readUser();
console.log(user);
</code></pre>
<h3>Database Call Comparison</h3>
<p><strong>Blocking (bad):</strong></p>
<pre><code class="language-javascript">const user = db.getUserSync(1);  // Server freeze
res.json(user);
</code></pre>
<p><strong>Non-blocking (good):</strong></p>
<pre><code class="language-javascript">db.getUser(1, (err, user) =&gt; {
  if (err) return res.status(500).json({ error: err });
  res.json(user);  // Server not frozen
});
</code></pre>
<p><strong>Non-blocking (async/await, best):</strong></p>
<pre><code class="language-javascript">async function handleRequest(req, res) {
  try {
    const user = await db.getUser(1);
    res.json(user);
  } catch (err) {
    res.status(500).json({ error: err });
  }
}
</code></pre>
<hr />
<h2>Real-World Examples</h2>
<h3>Example 1: Read File and Database</h3>
<p><strong>Wrong (blocking):</strong></p>
<pre><code class="language-javascript">const fs = require('fs');
const db = require('./db');

app.get('/profile/:id', (req, res) =&gt; {
  // Freeze server here
  const settings = fs.readFileSync('config.json');
  const user = db.getUserSync(req.params.id);
  
  res.json({ user, settings });
});
</code></pre>
<p>Timeline for 3 users:</p>
<pre><code>User 1: File read (2s) → DB query (3s) = 5s total
User 2: Wait... wait... wait... (5s)
User 3: Wait... wait... wait... (10s)
</code></pre>
<p><strong>Right (non-blocking):</strong></p>
<pre><code class="language-javascript">const fs = require('fs').promises;
const db = require('./db');

app.get('/profile/:id', async (req, res) =&gt; {
  try {
    // Both start at same time (parallel)
    const [settings, user] = await Promise.all([
      fs.readFile('config.json'),
      db.getUser(req.params.id)
    ]);
    
    res.json({ user, settings });
  } catch (err) {
    res.status(500).json({ error: err });
  }
});
</code></pre>
<p>Timeline for 3 users:</p>
<pre><code>User 1: Start both → Wait 3s → Done
User 2: Start both → Wait 3s → Done
User 3: Start both → Wait 3s → Done
Total: All 3 done in 3 seconds (not 15)
</code></pre>
<h3>Example 2: Loop with Non-Blocking</h3>
<p><strong>Wrong (blocking):</strong></p>
<pre><code class="language-javascript">const fs = require('fs');

function processFiles(filenames) {
  const results = [];
  
  for (const filename of filenames) {
    // Read each file one by one (SLOW)
    const data = fs.readFileSync(filename);
    results.push(data);
  }
  
  return results;
}

processFiles(['file1.txt', 'file2.txt', 'file3.txt']);
// Take 3 seconds (1s each)
</code></pre>
<p><strong>Right (non-blocking, parallel):</strong></p>
<pre><code class="language-javascript">const fs = require('fs').promises;

async function processFiles(filenames) {
  // Read all files at same time
  const promises = filenames.map(filename =&gt; 
    fs.readFile(filename)
  );
  
  const results = await Promise.all(promises);
  return results;
}

await processFiles(['file1.txt', 'file2.txt', 'file3.txt']);
// Take 1 second (all run together)
</code></pre>
<h3>Example 3: API Call with Non-Blocking</h3>
<p><strong>Wrong (blocking - would hang server):</strong></p>
<pre><code class="language-javascript">// Blocking network call (doesn't exist in Node.js)
const data = http.requestSync(url);  // NO
res.json(data);
</code></pre>
<p><strong>Right (non-blocking):</strong></p>
<pre><code class="language-javascript">const axios = require('axios');

app.get('/data', async (req, res) =&gt; {
  try {
    // Don't block - wait for response
    const response = await axios.get('https://api.example.com/data');
    res.json(response.data);
  } catch (err) {
    res.status(500).json({ error: err });
  }
});
</code></pre>
<p>Server handle 100 users at once. Each <code>await</code> not block others.</p>
<hr />
<h2>Common Mistakes</h2>
<h3>Mistake 1: Using Sync Methods in Production</h3>
<pre><code class="language-javascript">// ✗ Bad - freeze server
const data = fs.readFileSync('file.txt');

// ✓ Good - don't freeze
const data = await fs.promises.readFile('file.txt');
</code></pre>
<h3>Mistake 2: Forgetting Error Handling</h3>
<pre><code class="language-javascript">// ✗ Bad - error crash app
async function loadData() {
  const data = await fs.readFile('file.txt');
  console.log(data);
}

// ✓ Good - handle error
async function loadData() {
  try {
    const data = await fs.readFile('file.txt');
    console.log(data);
  } catch (err) {
    console.error('Error:', err);
  }
}
</code></pre>
<h3>Mistake 3: Sequential When Could Be Parallel</h3>
<pre><code class="language-javascript">// ✗ Bad - run one at time (3 seconds)
async function getData() {
  const users = await db.getUsers();
  const posts = await db.getPosts();
  const comments = await db.getComments();
  return { users, posts, comments };
}

// ✓ Good - run all together (1 second)
async function getData() {
  return Promise.all([
    db.getUsers(),
    db.getPosts(),
    db.getComments()
  ]);
}
</code></pre>
<h3>Mistake 4: Callback Hell (Before Understanding Promises)</h3>
<pre><code class="language-javascript">// ✗ Bad - nested and hard read
fs.readFile('file1.txt', (err, data1) =&gt; {
  fs.readFile('file2.txt', (err, data2) =&gt; {
    fs.readFile('file3.txt', (err, data3) =&gt; {
      console.log(data1, data2, data3);
    });
  });
});

// ✓ Good - use Promise.all
async function readFiles() {
  const [data1, data2, data3] = await Promise.all([
    fs.promises.readFile('file1.txt'),
    fs.promises.readFile('file2.txt'),
    fs.promises.readFile('file3.txt')
  ]);
  console.log(data1, data2, data3);
}
</code></pre>
<hr />
<h2>When to Block (Rare)</h2>
<p>Generally: don't block.</p>
<p>But rare cases:</p>
<ol>
<li><strong>Server startup</strong> - Load config before start</li>
<li><strong>CLI tools</strong> - Command line tool need blocking read</li>
<li><strong>One-time script</strong> - Not long-running server</li>
</ol>
<pre><code class="language-javascript">// OK to block on startup
const config = fs.readFileSync('config.json');

const app = express();
app.use(/* setup */);

// NOW use async everywhere
app.get('/data', async (req, res) =&gt; {
  const data = await getData();
  res.json(data);
});

app.listen(3000);
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Fix blocking code:</strong></p>
<pre><code class="language-javascript">// Given blocking code, rewrite with async/await
const fs = require('fs');

function loadData() {
  const users = fs.readFileSync('users.json');
  const posts = fs.readFileSync('posts.json');
  return { users, posts };
}

// Rewrite to non-blocking
</code></pre>
<p><strong>2. Build async API endpoint:</strong></p>
<pre><code class="language-javascript">// Create Express endpoint that:
// - Read user file from disk
// - Query database for user data
// - Return combined response
// Use async/await
</code></pre>
<p><strong>3. Parallel operations:</strong></p>
<pre><code class="language-javascript">// Write function that read 5 files
// Do NOT read one by one
// Read all at same time using Promise.all
</code></pre>
<p><strong>4. Error handling:</strong></p>
<pre><code class="language-javascript">// Add proper try/catch
// Handle file read errors
// Handle database errors
// Return error responses
</code></pre>
<p><strong>5. Performance test:</strong></p>
<pre><code class="language-javascript">// Create two versions:
// - Blocking (sequential read)
// - Non-blocking (parallel read)
// Test speed difference
// Measure time
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Blocking code</strong> = wait for operation. Nothing else happen.</p>
</li>
<li><p><strong>Non-blocking code</strong> = start operation, move on. Callback when done.</p>
</li>
<li><p><strong>Blocking freeze server</strong>. All users wait.</p>
</li>
<li><p><strong>Non-blocking</strong> allow server handle many users.</p>
</li>
<li><p><strong>Sync methods</strong> = <code>readFileSync</code>, <code>querySync</code>. Avoid in production.</p>
</li>
<li><p><strong>Async methods</strong> = <code>readFile</code>, <code>query</code>. Use these.</p>
</li>
<li><p><strong>Callbacks</strong> = function run later. Basic async pattern.</p>
</li>
<li><p><strong>Promises</strong> = cleaner callbacks. Chain operations.</p>
</li>
<li><p><strong>Async/await</strong> = easiest pattern. Look like normal code.</p>
</li>
<li><p><strong><code>async</code> function</strong> = return Promise automatically.</p>
</li>
<li><p><strong><code>await</code> keyword</strong> = pause until Promise done.</p>
</li>
<li><p><strong><code>try/catch</code></strong> = handle errors in async code.</p>
</li>
<li><p><strong><code>Promise.all</code></strong> = run multiple async at once (parallel).</p>
</li>
<li><p><strong>Sequential</strong> = one after another (slow).</p>
</li>
<li><p><strong>Parallel</strong> = all together (fast).</p>
</li>
<li><p><strong>3 users, 5 seconds each</strong> = blocking need 15 seconds total.</p>
</li>
<li><p><strong>3 users, 5 seconds each</strong> = non-blocking do 5 seconds total.</p>
</li>
<li><p><strong>Most operations are I/O</strong>: files, database, network. Use async.</p>
</li>
<li><p><strong>Block only on startup</strong>, not during request handling.</p>
</li>
</ul>
<p>Non-blocking code = fast servers. Fast servers = happy users.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[REST API Design Made Simple with Express.js
]]></title><description><![CDATA[REST API is a standard way for the client to communicate with the server. Instead of mysterious endpoints like /getUser or /fetchUserData, REST uses predictable HTTP methods and resource-based URLs. O]]></description><link>https://blog.harshx.in/rest-api-with-express-js</link><guid isPermaLink="true">https://blog.harshx.in/rest-api-with-express-js</guid><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 12:02:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/7e174b9e-350e-491a-a25d-e971bdb088d1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p> REST API is a standard way for the client to communicate with the server. Instead of mysterious endpoints like <code>/getUser</code> or <code>/fetchUserData</code>, REST uses predictable HTTP methods and resource-based URLs. Once you understand REST, building APIs becomes straightforward.</p>
<p>This is about understanding REST principles and building proper APIs with Express.</p>
<hr />
<h2>What REST API Means</h2>
<p>REST stands for Representational State Transfer. It's a set of rules for building APIs.</p>
<h3>Simple Definition</h3>
<p>REST is a standard way to structure requests and responses between client and server using HTTP methods and resource URLs.</p>
<h3>The Communication Problem</h3>
<p>Without REST, APIs are chaotic:</p>
<pre><code>GET /getUser?id=1
POST /fetchUserData
PUT /updateUserInfo
DELETE /removeUser?userId=1
GET /getAllUsers
</code></pre>
<p>Different names for similar operations. Confusing.</p>
<p>With REST, APIs are predictable:</p>
<pre><code>GET /users/1        (get user)
POST /users         (create user)
PUT /users/1        (update user)
DELETE /users/1     (delete user)
GET /users          (get all users)
</code></pre>
<p>Same resource, different methods. Crystal clear.</p>
<h3>Real Analogy</h3>
<p>Think of a restaurant's menu (API):</p>
<p>Without REST:</p>
<pre><code>bringSoup
bringBread
removePlate
giveBill
bringsalad
</code></pre>
<p>Confusing. No pattern.</p>
<p>With REST:</p>
<pre><code>Action: BRING, Resource: SOUP
Action: BRING, Resource: BREAD
Action: REMOVE, Resource: PLATE
Action: GIVE, Resource: BILL
</code></pre>
<p>Clear pattern. Easy to understand.</p>
<h3>Why REST Matters</h3>
<p>REST makes APIs:</p>
<ul>
<li>Predictable (you can guess the URL)</li>
<li>Consistent (same patterns everywhere)</li>
<li>Easy to document</li>
<li>Easy for clients to use</li>
<li>Standard across the web</li>
</ul>
<hr />
<h2>Resources in REST Architecture</h2>
<p>Resources are the things your API manages.</p>
<h3>What is a Resource?</h3>
<p>A resource is anything your API handles: users, posts, comments, products, orders.</p>
<h3>Resource URLs</h3>
<p>Resources are accessed via URLs:</p>
<pre><code class="language-plaintext">/users          (users resource)
/posts          (posts resource)
/comments       (comments resource)
/products       (products resource)
</code></pre>
<h3>Specific Resources</h3>
<p>Access specific resources with IDs:</p>
<pre><code class="language-plaintext">/users/1        (user with ID 1)
/posts/42       (post with ID 42)
/comments/100   (comment with ID 100)
</code></pre>
<h3>Nested Resources</h3>
<p>Related resources can be nested:</p>
<pre><code class="language-plaintext">/users/1/posts           (posts by user 1)
/posts/42/comments       (comments on post 42)
/users/1/posts/5/comments (comments on post 5 by user 1)
</code></pre>
<h3>Resource Collections vs Specific Resources</h3>
<pre><code class="language-plaintext">/users          (collection: all users)
/users/1        (specific: user with ID 1)

/posts          (collection: all posts)
/posts/42       (specific: post with ID 42)
</code></pre>
<h3>Naming Conventions</h3>
<p>Use plural nouns for resources:</p>
<pre><code class="language-plaintext">✓ /users        (correct)
✗ /user         (incorrect)

✓ /posts        (correct)
✗ /post         (incorrect)

✓ /comments     (correct)
✗ /comment      (incorrect)
</code></pre>
<p>Use lowercase and hyphens for multi-word resources:</p>
<pre><code class="language-plaintext">✓ /user-profiles
✓ /blog-posts
✓ /shopping-carts

✗ /userProfiles (camelCase)
✗ /BlogPosts    (PascalCase)
</code></pre>
<hr />
<h2>HTTP Methods: GET, POST, PUT, DELETE</h2>
<p>HTTP methods tell the server what action to perform on a resource.</p>
<h3>GET: Retrieve Data</h3>
<p>GET retrieves existing data. Safe and doesn't change anything.</p>
<pre><code class="language-plaintext">GET /users           → Get all users
GET /users/1         → Get user with ID 1
GET /users/1/posts   → Get posts by user 1
</code></pre>
<h3>Code Example: GET</h3>
<pre><code class="language-javascript">const express = require("express");
const app = express();

// Get all users
app.get("/users", (req, res) =&gt; {
  const users = [
    { id: 1, name: "Alice" },
    { id: 2, name: "Bob" }
  ];
  res.json(users);
});

// Get specific user
app.get("/users/:id", (req, res) =&gt; {
  const userId = req.params.id;
  const user = { id: userId, name: "Alice" };
  res.json(user);
});
</code></pre>
<h3>POST: Create Data</h3>
<p>POST creates new resources.</p>
<pre><code class="language-plaintext">POST /users              → Create new user
POST /posts              → Create new post
POST /users/1/posts      → Create post for user 1
</code></pre>
<p>The request body contains the data to create.</p>
<h3>Code Example: POST</h3>
<pre><code class="language-javascript">app.use(express.json());

// Create new user
app.post("/users", (req, res) =&gt; {
  const newUser = {
    id: 3,
    name: req.body.name,
    email: req.body.email
  };
  
  res.status(201).json(newUser);
});
</code></pre>
<p>Test with curl:</p>
<pre><code class="language-bash">curl -X POST http://localhost:3000/users \
  -H "Content-Type: application/json" \
  -d '{"name":"Charlie","email":"charlie@example.com"}'
</code></pre>
<h3>PUT: Update Data</h3>
<p>PUT updates entire resources.</p>
<pre><code class="language-plaintext">PUT /users/1        → Update user 1
PUT /posts/42       → Update post 42
</code></pre>
<p>The request body contains the updated data.</p>
<h3>Code Example: PUT</h3>
<pre><code class="language-javascript">// Update entire user
app.put("/users/:id", (req, res) =&gt; {
  const userId = req.params.id;
  const updatedUser = {
    id: userId,
    name: req.body.name,
    email: req.body.email,
    age: req.body.age
  };
  
  res.json(updatedUser);
});
</code></pre>
<p>Test with curl:</p>
<pre><code class="language-bash">curl -X PUT http://localhost:3000/users/1 \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice Updated","email":"alice.new@example.com","age":26}'
</code></pre>
<h3>PATCH: Partial Update</h3>
<p>PATCH updates specific fields (not full replacement).</p>
<pre><code class="language-plaintext">PATCH /users/1      → Update some fields of user 1
</code></pre>
<h3>Code Example: PATCH</h3>
<pre><code class="language-javascript">// Update specific fields
app.patch("/users/:id", (req, res) =&gt; {
  const userId = req.params.id;
  
  // Only update provided fields
  const updates = {
    id: userId,
    name: req.body.name || "Alice",  // Keep existing if not provided
    email: req.body.email || "alice@example.com"
  };
  
  res.json(updates);
});
</code></pre>
<h3>DELETE: Remove Data</h3>
<p>DELETE removes resources.</p>
<pre><code class="language-plaintext">DELETE /users/1     → Delete user 1
DELETE /posts/42    → Delete post 42
</code></pre>
<h3>Code Example: DELETE</h3>
<pre><code class="language-javascript">// Delete user
app.delete("/users/:id", (req, res) =&gt; {
  const userId = req.params.id;
  
  res.json({ message: `User ${userId} deleted` });
});
</code></pre>
<p>Test with curl:</p>
<pre><code class="language-bash">curl -X DELETE http://localhost:3000/users/1
</code></pre>
<h3>CRUD vs HTTP Methods</h3>
<pre><code class="language-plaintext">CRUD Operation    HTTP Method    Example
─────────────────────────────────────────────
Create            POST           POST /users
Read              GET            GET /users/1
Update            PUT/PATCH      PUT /users/1
Delete            DELETE         DELETE /users/1
</code></pre>
<hr />
<h2>Status Codes Basics</h2>
<p>Status codes tell the client if the request succeeded or failed.</p>
<h3>2xx: Success</h3>
<p>Request was successful.</p>
<pre><code class="language-plaintext">200 OK              - Request succeeded
201 Created         - Resource created
204 No Content      - Success, no data to return
</code></pre>
<h3>4xx: Client Error</h3>
<p>Something wrong with the request.</p>
<pre><code class="language-plaintext">400 Bad Request     - Invalid request data
401 Unauthorized    - Not authenticated
403 Forbidden       - Authenticated but not allowed
404 Not Found       - Resource doesn't exist
</code></pre>
<h3>5xx: Server Error</h3>
<p>Something wrong on the server.</p>
<pre><code class="language-plaintext">500 Internal Server Error - Server error
503 Service Unavailable   - Server down
</code></pre>
<h3>Using Status Codes</h3>
<pre><code class="language-javascript">app.post("/users", (req, res) =&gt; {
  if (!req.body.email) {
    return res.status(400).json({ error: "Email required" });
  }
  
  const newUser = { id: 1, name: req.body.name };
  res.status(201).json(newUser);  // 201 Created
});

app.get("/users/:id", (req, res) =&gt; {
  const user = findUser(req.params.id);
  
  if (!user) {
    return res.status(404).json({ error: "User not found" });
  }
  
  res.status(200).json(user);  // 200 OK
});
</code></pre>
<h3>Common Status Codes</h3>
<pre><code class="language-plaintext">GET request         → 200 OK
POST success        → 201 Created
No content to show  → 204 No Content
Invalid request     → 400 Bad Request
Not authenticated   → 401 Unauthorized
Resource not found  → 404 Not Found
Server error        → 500 Internal Server Error
</code></pre>
<hr />
<h2>Designing Routes Using REST Principles</h2>
<h3>Users Resource Example</h3>
<pre><code class="language-plaintext">GET /users                  → Get all users
GET /users/1                → Get user 1
POST /users                 → Create new user
PUT /users/1                → Update user 1
PATCH /users/1              → Partially update user 1
DELETE /users/1             → Delete user 1
</code></pre>
<h3>Posts Resource Example</h3>
<pre><code class="language-plaintext">GET /posts                  → Get all posts
GET /posts/42               → Get post 42
POST /posts                 → Create new post
PUT /posts/42               → Update post 42
DELETE /posts/42            → Delete post 42
</code></pre>
<h3>Nested Resources</h3>
<p>User's posts:</p>
<pre><code class="language-plaintext">GET /users/1/posts          → Get posts by user 1
POST /users/1/posts         → Create post for user 1
GET /users/1/posts/5        → Get post 5 by user 1
DELETE /users/1/posts/5     → Delete post 5 by user 1
</code></pre>
<h3>Complete API Structure</h3>
<pre><code class="language-plaintext">Users
├─ GET /users               (list all)
├─ POST /users              (create)
├─ GET /users/1             (get one)
├─ PUT /users/1             (update)
└─ DELETE /users/1          (delete)

Posts
├─ GET /posts               (list all)
├─ POST /posts              (create)
├─ GET /posts/1             (get one)
├─ PUT /posts/1             (update)
└─ DELETE /posts/1          (delete)

User's Posts
├─ GET /users/1/posts       (user's posts)
└─ POST /users/1/posts      (user creates post)
</code></pre>
<hr />
<h2>REST Request-Response Lifecycle</h2>
<pre><code class="language-plaintext">Client sends request
├─ Method: POST
├─ URL: /users
└─ Body: { name: "Alice", email: "alice@example.com" }
      |
      v
Server receives request
      |
      v
Server validates data
├─ Valid? → Continue
└─ Invalid? → Return 400 error
      |
      v
Server creates resource
├─ Success? → Continue
└─ Error? → Return 500 error
      |
      v
Server sends response
├─ Status: 201 Created
└─ Body: { id: 1, name: "Alice", email: "alice@example.com" }
      |
      v
Client receives response
      |
      v
Client displays data or error
</code></pre>
<hr />
<h2>Example Resource: Users</h2>
<p>Building a complete users API.</p>
<h3>Simple Users API</h3>
<pre><code class="language-javascript">const express = require("express");
const app = express();
app.use(express.json());

// In-memory database
let users = [
  { id: 1, name: "Alice", email: "alice@example.com" },
  { id: 2, name: "Bob", email: "bob@example.com" }
];

let nextId = 3;

// GET all users
app.get("/users", (req, res) =&gt; {
  res.json(users);
});

// GET specific user
app.get("/users/:id", (req, res) =&gt; {
  const user = users.find(u =&gt; u.id === parseInt(req.params.id));
  
  if (!user) {
    return res.status(404).json({ error: "User not found" });
  }
  
  res.json(user);
});

// POST create user
app.post("/users", (req, res) =&gt; {
  // Validate
  if (!req.body.name || !req.body.email) {
    return res.status(400).json({ error: "Name and email required" });
  }
  
  // Create
  const newUser = {
    id: nextId++,
    name: req.body.name,
    email: req.body.email
  };
  
  users.push(newUser);
  
  // Return 201 Created
  res.status(201).json(newUser);
});

// PUT update user
app.put("/users/:id", (req, res) =&gt; {
  const user = users.find(u =&gt; u.id === parseInt(req.params.id));
  
  if (!user) {
    return res.status(404).json({ error: "User not found" });
  }
  
  // Validate
  if (!req.body.name || !req.body.email) {
    return res.status(400).json({ error: "Name and email required" });
  }
  
  // Update
  user.name = req.body.name;
  user.email = req.body.email;
  
  res.json(user);
});

// PATCH partial update
app.patch("/users/:id", (req, res) =&gt; {
  const user = users.find(u =&gt; u.id === parseInt(req.params.id));
  
  if (!user) {
    return res.status(404).json({ error: "User not found" });
  }
  
  // Update only provided fields
  if (req.body.name) user.name = req.body.name;
  if (req.body.email) user.email = req.body.email;
  
  res.json(user);
});

// DELETE user
app.delete("/users/:id", (req, res) =&gt; {
  const index = users.findIndex(u =&gt; u.id === parseInt(req.params.id));
  
  if (index === -1) {
    return res.status(404).json({ error: "User not found" });
  }
  
  const deletedUser = users.splice(index, 1);
  res.json({ message: "User deleted", user: deletedUser[0] });
});

app.listen(3000, () =&gt; {
  console.log("API running on http://localhost:3000");
});
</code></pre>
<h3>Testing the API</h3>
<p>Get all users:</p>
<pre><code class="language-bash">curl http://localhost:3000/users
# [{"id":1,"name":"Alice","email":"alice@example.com"},{"id":2,"name":"Bob","email":"bob@example.com"}]
</code></pre>
<p>Get one user:</p>
<pre><code class="language-bash">curl http://localhost:3000/users/1
# {"id":1,"name":"Alice","email":"alice@example.com"}
</code></pre>
<p>Create user:</p>
<pre><code class="language-bash">curl -X POST http://localhost:3000/users \
  -H "Content-Type: application/json" \
  -d '{"name":"Charlie","email":"charlie@example.com"}'
# {"id":3,"name":"Charlie","email":"charlie@example.com"}
</code></pre>
<p>Update user:</p>
<pre><code class="language-bash">curl -X PUT http://localhost:3000/users/1 \
  -H "Content-Type: application/json" \
  -d '{"name":"Alice Updated","email":"alice.new@example.com"}'
# {"id":1,"name":"Alice Updated","email":"alice.new@example.com"}
</code></pre>
<p>Partial update:</p>
<pre><code class="language-bash">curl -X PATCH http://localhost:3000/users/1 \
  -H "Content-Type: application/json" \
  -d '{"email":"newemail@example.com"}'
# {"id":1,"name":"Alice Updated","email":"newemail@example.com"}
</code></pre>
<p>Delete user:</p>
<pre><code class="language-bash">curl -X DELETE http://localhost:3000/users/1
# {"message":"User deleted","user":{"id":1,"name":"Alice Updated","email":"newemail@example.com"}}
</code></pre>
<hr />
<h2>API Request-Response Examples</h2>
<h3>GET Request</h3>
<pre><code class="language-plaintext">Request:
────────
GET /users/1 HTTP/1.1
Host: localhost:3000

Response:
─────────
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id": 1,
  "name": "Alice",
  "email": "alice@example.com"
}
</code></pre>
<h3>POST Request</h3>
<pre><code class="language-plaintext">Request:
────────
POST /users HTTP/1.1
Host: localhost:3000
Content-Type: application/json

{
  "name": "Charlie",
  "email": "charlie@example.com"
}

Response:
─────────
HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": 3,
  "name": "Charlie",
  "email": "charlie@example.com"
}
</code></pre>
<h3>Error Response</h3>
<pre><code class="language-plaintext">Request:
────────
GET /users/999 HTTP/1.1
Host: localhost:3000

Response:
─────────
HTTP/1.1 404 Not Found
Content-Type: application/json

{
  "error": "User not found"
}
</code></pre>
<hr />
<h2>Best Practices for REST APIs</h2>
<h3>Use Correct HTTP Methods</h3>
<pre><code class="language-javascript">// ✓ Correct
GET /users          (retrieve)
POST /users         (create)
PUT /users/1        (update)
DELETE /users/1     (delete)

// ✗ Wrong
GET /deleteUser?id=1     (wrong method)
POST /getUsers           (should be GET)
GET /updateUser?id=1     (wrong method)
</code></pre>
<h3>Use Correct Status Codes</h3>
<pre><code class="language-javascript">// ✓ Correct
app.post("/users", (req, res) =&gt; {
  res.status(201).json(newUser);  // 201 for create
});

app.get("/users/:id", (req, res) =&gt; {
  if (!user) {
    return res.status(404).json({ error: "Not found" });  // 404 for missing
  }
  res.json(user);  // 200 for success
});

// ✗ Wrong
app.post("/users", (req, res) =&gt; {
  res.json(newUser);  // No status (defaults to 200, should be 201)
});
</code></pre>
<h3>Use Plural Nouns for Resources</h3>
<pre><code class="language-javascript">// ✓ Correct
GET /users
POST /posts
DELETE /comments/1

// ✗ Wrong
GET /user
POST /post
DELETE /comment/1
</code></pre>
<h3>Use Logical Nesting</h3>
<pre><code class="language-javascript">// ✓ Correct (related resources)
GET /users/1/posts      (user's posts)

// ✗ Wrong (too deeply nested)
GET /users/1/posts/2/comments/3/author/replies
</code></pre>
<h3>Validate Input</h3>
<pre><code class="language-javascript">app.post("/users", (req, res) =&gt; {
  // ✓ Validate
  if (!req.body.name || !req.body.email) {
    return res.status(400).json({ error: "Invalid data" });
  }
  
  // Process...
});
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Plan a products API:</strong></p>
<pre><code class="language-javascript">// Design routes for products resource
// GET /products
// GET /products/:id
// POST /products
// PUT /products/:id
// DELETE /products/:id
// Write route signatures
</code></pre>
<p><strong>2. Build simple users API:</strong></p>
<pre><code class="language-javascript">// Create Express server
// Implement all CRUD operations for users
// Test each endpoint with curl
// Return correct status codes
</code></pre>
<p><strong>3. Add validation:</strong></p>
<pre><code class="language-javascript">// Add input validation to POST /users
// Check required fields
// Return 400 for invalid data
// Test with valid and invalid requests
</code></pre>
<p><strong>4. Nested resources:</strong></p>
<pre><code class="language-javascript">// Create users and posts resources
// Implement GET /users/:id/posts
// Get all posts for a specific user
// Test the nested route
</code></pre>
<p><strong>5. Error handling:</strong></p>
<pre><code class="language-javascript">// Add proper error handling
// Return 404 for missing resources
// Return 400 for bad requests
// Return 500 for server errors
// Test error scenarios
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>REST</strong> is a standard for building predictable, consistent APIs.</p>
</li>
<li><p><strong>Resources</strong> are things your API manages: users, posts, products.</p>
</li>
<li><p><strong>HTTP methods</strong> tell the server what action to perform: GET, POST, PUT, DELETE.</p>
</li>
<li><p><strong>GET</strong> retrieves data without changing anything.</p>
</li>
<li><p><strong>POST</strong> creates new resources.</p>
</li>
<li><p><strong>PUT</strong> updates entire resources.</p>
</li>
<li><p><strong>PATCH</strong> updates specific fields.</p>
</li>
<li><p><strong>DELETE</strong> removes resources.</p>
</li>
<li><p><strong>Status codes</strong> tell the client if the request succeeded or failed.</p>
</li>
<li><p><strong>2xx codes</strong> indicate success (200 OK, 201 Created).</p>
</li>
<li><p><strong>4xx codes</strong> indicate client errors (400 Bad Request, 404 Not Found).</p>
</li>
<li><p><strong>5xx codes</strong> indicate server errors (500 Internal Server Error).</p>
</li>
<li><p>Use <strong>plural nouns</strong> for resource names: <code>/users</code>, not <code>/user</code>.</p>
</li>
<li><p>Use <strong>lowercase and hyphens</strong> for multi-word resources: <code>/user-profiles</code>.</p>
</li>
<li><p><strong>Collection endpoints</strong> return all resources: <code>GET /users</code>.</p>
</li>
<li><p><strong>Specific endpoints</strong> use IDs: <code>GET /users/1</code>.</p>
</li>
<li><p><strong>Nested resources</strong> show relationships: <code>GET /users/1/posts</code>.</p>
</li>
<li><p><strong>Request validation</strong> prevents bad data from being saved.</p>
</li>
<li><p><strong>Proper status codes</strong> help clients understand what happened.</p>
</li>
<li><p><strong>Consistent naming</strong> makes APIs predictable and easy to use.</p>
</li>
<li><p><strong>REST design</strong> makes APIs intuitive even for new users.</p>
</li>
</ul>
<p>REST APIs are the standard for building modern web services.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Map and Set in JavaScript
]]></title><description><![CDATA[Map and Set are better ways to store data than objects and arrays. Map stores paired data like objects, but works with any data type as keys. Set stores only unique values, making duplicates impossibl]]></description><link>https://blog.harshx.in/map-and-set-in-javascript</link><guid isPermaLink="true">https://blog.harshx.in/map-and-set-in-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 11:53:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/b9926e1b-e5e4-4a0d-948a-c62589cd22cc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p> Map and Set are better ways to store data than objects and arrays. Map stores paired data like objects, but works with any data type as keys. Set stores only unique values, making duplicates impossible. Both are faster and more predictable than their traditional counterparts.</p>
<p>This is about understanding Map and Set and knowing when to use them.</p>
<hr />
<h2>What is Map?</h2>
<p>Map is a data structure for storing key-value pairs. Like an object, but better.</p>
<h3>Simple Definition</h3>
<p>A Map is a collection of paired data: each key has a value.</p>
<pre><code class="language-javascript">// Empty Map
const map = new Map();

// Add key-value pairs
map.set("name", "Alice");
map.set("age", 25);
map.set("email", "alice@example.com");

// Get values
console.log(map.get("name"));   // "Alice"
console.log(map.get("age"));    // 25
console.log(map.get("email"));  // "alice@example.com"
</code></pre>
<h3>Creating a Map</h3>
<pre><code class="language-javascript">// Empty Map
const emptyMap = new Map();

// Map from array of pairs
const mapFromArray = new Map([
  ["name", "Alice"],
  ["age", 25],
  ["city", "NYC"]
]);

// Map from another Map
const copyMap = new Map(mapFromArray);
</code></pre>
<h3>Basic Map Methods</h3>
<pre><code class="language-javascript">const map = new Map();

// Add
map.set("key1", "value1");
map.set("key2", "value2");

// Get
console.log(map.get("key1"));  // "value1"

// Check if exists
console.log(map.has("key1"));  // true
console.log(map.has("key3"));  // false

// Delete
map.delete("key1");
console.log(map.has("key1"));  // false

// Clear all
map.clear();
console.log(map.size);  // 0

// Size
map.set("a", 1);
map.set("b", 2);
console.log(map.size);  // 2
</code></pre>
<h3>Real Example: User Preferences</h3>
<pre><code class="language-javascript">const userPreferences = new Map();

userPreferences.set("theme", "dark");
userPreferences.set("language", "en");
userPreferences.set("notifications", true);
userPreferences.set("timezone", "UTC");

// Check preference
if (userPreferences.has("theme")) {
  console.log("Theme:", userPreferences.get("theme"));
}

// Update
userPreferences.set("theme", "light");

// Iterate
userPreferences.forEach((value, key) =&gt; {
  console.log(`\({key}: \){value}`);
});
</code></pre>
<hr />
<h2>What is Set?</h2>
<p>Set is a collection of unique values. No duplicates allowed.</p>
<h3>Simple Definition</h3>
<p>A Set is a collection where each value appears only once. Duplicates are automatically removed.</p>
<pre><code class="language-javascript">// Create Set
const set = new Set();

// Add values
set.add("apple");
set.add("banana");
set.add("orange");
set.add("apple");  // Duplicate, ignored

console.log(set);  // Set(3) { 'apple', 'banana', 'orange' }
</code></pre>
<p>Only three items, not four. The duplicate "apple" was ignored.</p>
<h3>Creating a Set</h3>
<pre><code class="language-javascript">// From array
const set = new Set([1, 2, 3, 4, 4, 5, 5, 5]);
console.log(set);  // Set(5) { 1, 2, 3, 4, 5 }

// From string
const charSet = new Set("hello");
console.log(charSet);  // Set(4) { 'h', 'e', 'l', 'o' }

// Empty Set
const emptySet = new Set();
</code></pre>
<h3>Basic Set Methods</h3>
<pre><code class="language-javascript">const set = new Set();

// Add
set.add(1);
set.add(2);
set.add(3);

// Check if exists
console.log(set.has(2));  // true
console.log(set.has(4));  // false

// Delete
set.delete(2);
console.log(set.has(2));  // false

// Clear all
set.clear();
console.log(set.size);  // 0

// Size
set.add(1);
set.add(2);
console.log(set.size);  // 2

// Iterate
set.forEach((value) =&gt; {
  console.log(value);
});
</code></pre>
<h3>Real Example: Unique Tags</h3>
<pre><code class="language-javascript">const tags = new Set();

// User adds tags
tags.add("javascript");
tags.add("webdev");
tags.add("node.js");
tags.add("javascript");  // Duplicate ignored

console.log(tags.size);  // 3

// Check tag exists
if (tags.has("webdev")) {
  console.log("Has webdev tag");
}

// Remove tag
tags.delete("node.js");

// Convert back to array
const tagArray = Array.from(tags);
console.log(tagArray);  // ['javascript', 'webdev']
</code></pre>
<h3>Set Uniqueness Representation</h3>
<pre><code class="language-plaintext">Adding values to a Set
      |
      v
[1, 2, 3, 4, 4, 5, 5]
|     |     |     |
├─────┼─────┼─────┤
v     v     v     v
Add 1: ✓ (new)
Add 2: ✓ (new)
Add 3: ✓ (new)
Add 4: ✓ (new)
Add 4: ✗ (duplicate, ignored)
Add 5: ✓ (new)
Add 5: ✗ (duplicate, ignored)
Add 5: ✗ (duplicate, ignored)
      |
      v
Result: Set(5) { 1, 2, 3, 4, 5 }
</code></pre>
<hr />
<h2>Difference Between Map and Object</h2>
<h3>Objects Store Key-Value Pairs Too</h3>
<pre><code class="language-javascript">const obj = {
  name: "Alice",
  age: 25,
  email: "alice@example.com"
};

console.log(obj.name);  // "Alice"
console.log(obj["age"]);  // 25
</code></pre>
<p>Objects look similar to Map. But there are important differences.</p>
<h3>Difference 1: Key Types</h3>
<p>Objects accept only strings and symbols as keys:</p>
<pre><code class="language-javascript">const obj = {};

obj["name"] = "Alice";        // ✓ String key
obj[1] = "one";               // ✗ Converted to string "1"
obj[true] = "yes";            // ✗ Converted to string "true"

console.log(obj[1]);          // "one" (key is "1", not 1)
</code></pre>
<p>Maps accept any data type as keys:</p>
<pre><code class="language-javascript">const map = new Map();

map.set("name", "Alice");     // ✓ String key
map.set(1, "one");            // ✓ Number key
map.set(true, "yes");         // ✓ Boolean key
map.set({}, "object key");    // ✓ Object key
map.set([], "array key");     // ✓ Array key

console.log(map.get(1));      // "one" (key is number 1, not "1")
</code></pre>
<h3>Difference 2: Size Property</h3>
<p>Objects don't have a size property:</p>
<pre><code class="language-javascript">const obj = { a: 1, b: 2, c: 3 };

console.log(obj.length);      // undefined
// Must count keys manually
console.log(Object.keys(obj).length);  // 3
</code></pre>
<p>Maps have a size property:</p>
<pre><code class="language-javascript">const map = new Map([["a", 1], ["b", 2], ["c", 3]]);

console.log(map.size);        // 3 (instant)
</code></pre>
<h3>Difference 3: Iteration</h3>
<p>Objects need Object.keys() or for...in:</p>
<pre><code class="language-javascript">const obj = { name: "Alice", age: 25 };

// Need to get keys first
Object.keys(obj).forEach(key =&gt; {
  console.log(`\({key}: \){obj[key]}`);
});

// Or use for...in (but gets inherited properties too)
for (let key in obj) {
  console.log(`\({key}: \){obj[key]}`);
}
</code></pre>
<p>Maps iterate directly:</p>
<pre><code class="language-javascript">const map = new Map([["name", "Alice"], ["age", 25]]);

// Iterate directly
map.forEach((value, key) =&gt; {
  console.log(`\({key}: \){value}`);
});

// Or use for...of
for (const [key, value] of map) {
  console.log(`\({key}: \){value}`);
}
</code></pre>
<h3>Difference 4: Performance</h3>
<p>Maps are optimized for frequent additions/deletions:</p>
<pre><code class="language-javascript">// Adding/deleting from objects is slower
const obj = {};
for (let i = 0; i &lt; 10000; i++) {
  obj[i] = i;
}
delete obj[5000];  // Slower

// Maps are faster
const map = new Map();
for (let i = 0; i &lt; 10000; i++) {
  map.set(i, i);
}
map.delete(5000);  // Faster
</code></pre>
<h3>Difference 5: Prototype Chain</h3>
<p>Objects inherit from Object.prototype:</p>
<pre><code class="language-javascript">const obj = {};

console.log(obj.toString);  // Inherited from Object.prototype
</code></pre>
<p>Maps don't have this baggage:</p>
<pre><code class="language-javascript">const map = new Map();

console.log(map.toString);  // undefined (unless explicitly set)
</code></pre>
<h3>When to Use Map vs Object</h3>
<table>
<thead>
<tr>
<th>Situation</th>
<th>Use Map</th>
<th>Use Object</th>
</tr>
</thead>
<tbody><tr>
<td>Many key-value pairs</td>
<td>Yes</td>
<td>No (slower)</td>
</tr>
<tr>
<td>Non-string keys</td>
<td>Yes</td>
<td>No (converted)</td>
</tr>
<tr>
<td>Need size property</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Need frequent add/delete</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>JSON serialization</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Simple configuration</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Performance critical</td>
<td>Yes</td>
<td>No</td>
</tr>
</tbody></table>
<hr />
<h2>Difference Between Set and Array</h2>
<h3>Arrays Store Values Too</h3>
<pre><code class="language-javascript">const arr = [1, 2, 3, 4, 5];

console.log(arr[0]);  // 1
console.log(arr.length);  // 5
</code></pre>
<p>Arrays look similar to Set. But there are key differences.</p>
<h3>Difference 1: Uniqueness</h3>
<p>Arrays allow duplicates:</p>
<pre><code class="language-javascript">const arr = [1, 2, 3, 4, 4, 5, 5, 5];

console.log(arr.length);  // 8 (includes duplicates)
</code></pre>
<p>Sets don't allow duplicates:</p>
<pre><code class="language-javascript">const set = new Set([1, 2, 3, 4, 4, 5, 5, 5]);

console.log(set.size);  // 5 (duplicates removed)
</code></pre>
<h3>Difference 2: Checking Membership</h3>
<p>Arrays need to search:</p>
<pre><code class="language-javascript">const arr = [1, 2, 3, 4, 5];

// Slow for large arrays
console.log(arr.includes(3));  // true
console.log(arr.indexOf(3));   // 2
</code></pre>
<p>Sets have instant lookup:</p>
<pre><code class="language-javascript">const set = new Set([1, 2, 3, 4, 5]);

console.log(set.has(3));  // true (instant, very fast)
</code></pre>
<h3>Difference 3: Iteration Methods</h3>
<p>Arrays have many methods:</p>
<pre><code class="language-javascript">const arr = [1, 2, 3, 4, 5];

arr.map(x =&gt; x * 2);         // Transform
arr.filter(x =&gt; x &gt; 2);      // Filter
arr.reduce((a, b) =&gt; a + b); // Aggregate
arr.find(x =&gt; x === 3);      // Find one
arr.some(x =&gt; x &gt; 3);        // Check any
arr.every(x =&gt; x &gt; 0);       // Check all
</code></pre>
<p>Sets have basic iteration:</p>
<pre><code class="language-javascript">const set = new Set([1, 2, 3, 4, 5]);

// Can use spread operator for array methods
[...set].map(x =&gt; x * 2);
[...set].filter(x =&gt; x &gt; 2);
</code></pre>
<h3>Difference 4: Order</h3>
<p>Arrays maintain insertion order (always):</p>
<pre><code class="language-javascript">const arr = [5, 1, 3, 2, 4];

console.log(arr[0]);  // 5 (original order)
</code></pre>
<p>Sets maintain insertion order (in modern JS):</p>
<pre><code class="language-javascript">const set = new Set([5, 1, 3, 2, 4]);

// Iteration order: 5, 1, 3, 2, 4
set.forEach(val =&gt; console.log(val));
</code></pre>
<h3>Difference 5: Memory Usage</h3>
<p>Arrays use less memory for small amounts:</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];  // Small array
</code></pre>
<p>Sets use more memory for small amounts, less for large:</p>
<pre><code class="language-javascript">const set = new Set([1, 2, 3]);  // More memory overhead initially
</code></pre>
<p>For large collections with duplicates, Sets win.</p>
<h3>When to Use Set vs Array</h3>
<table>
<thead>
<tr>
<th>Situation</th>
<th>Use Set</th>
<th>Use Array</th>
</tr>
</thead>
<tbody><tr>
<td>Unique values only</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Need .map(), .filter()</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Checking membership</td>
<td>Yes</td>
<td>No (slower)</td>
</tr>
<tr>
<td>Many duplicates</td>
<td>Yes</td>
<td>No</td>
</tr>
<tr>
<td>Need specific order</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Simple list</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Performance critical</td>
<td>Yes</td>
<td>No</td>
</tr>
</tbody></table>
<hr />
<h2>Map Key-Value Storage Visual</h2>
<pre><code class="language-plaintext">Map Storage
      |
      ├─ Key: "name"      → Value: "Alice"
      |
      ├─ Key: 25          → Value: "age"
      |
      ├─ Key: true        → Value: "verified"
      |
      └─ Key: {id: 1}     → Value: "user object"

Each key maps to exactly one value
Keys can be ANY data type
Fast lookup by key
</code></pre>
<hr />
<h2>When to Use Map and Set</h2>
<h3>Use Map When</h3>
<p>You need key-value storage with:</p>
<pre><code class="language-javascript">// Complex keys
const cache = new Map();
cache.set({ userId: 1 }, { name: "Alice", email: "alice@example.com" });
cache.set({ userId: 2 }, { name: "Bob", email: "bob@example.com" });

console.log(cache.get({ userId: 1 }));  // Won't work (different object)
</code></pre>
<p>Or frequent additions/deletions:</p>
<pre><code class="language-javascript">const sessions = new Map();

// Add session
sessions.set("session-123", { userId: 1, time: Date.now() });

// Check if exists
if (sessions.has("session-123")) {
  console.log("Session valid");
}

// Remove when expired
sessions.delete("session-123");

// How many sessions?
console.log(sessions.size);
</code></pre>
<h3>Map Real Examples</h3>
<p>Caching:</p>
<pre><code class="language-javascript">const cache = new Map();

function getUser(id) {
  if (cache.has(id)) {
    return cache.get(id);
  }
  
  const user = fetchUserFromDatabase(id);
  cache.set(id, user);
  return user;
}
</code></pre>
<p>User preferences:</p>
<pre><code class="language-javascript">const preferences = new Map();

preferences.set("theme", "dark");
preferences.set("language", "en");
preferences.set("notifications", true);

console.log(preferences.get("theme"));
</code></pre>
<h3>Use Set When</h3>
<p>You need unique values:</p>
<pre><code class="language-javascript">// Remove duplicates
const tags = new Set(["javascript", "webdev", "javascript", "node"]);
console.log(tags);  // Set { 'javascript', 'webdev', 'node' }

// Check membership
if (tags.has("javascript")) {
  console.log("Has javascript tag");
}
</code></pre>
<p>Or checking membership is critical:</p>
<pre><code class="language-javascript">// Fast lookup for permissions
const adminUsers = new Set(["user123", "user456", "user789"]);

if (adminUsers.has(userId)) {
  console.log("Admin access granted");
}
</code></pre>
<h3>Set Real Examples</h3>
<p>Unique values:</p>
<pre><code class="language-javascript">// Get unique users who visited page
const visitors = new Set();
visitors.add("alice");
visitors.add("bob");
visitors.add("alice");  // Ignored

console.log(visitors.size);  // 2
</code></pre>
<p>Allowed values:</p>
<pre><code class="language-javascript">// Valid statuses
const validStatuses = new Set(["pending", "active", "completed", "cancelled"]);

function isValidStatus(status) {
  return validStatuses.has(status);
}

console.log(isValidStatus("active"));    // true
console.log(isValidStatus("invalid"));   // false
</code></pre>
<p>Remove duplicates from array:</p>
<pre><code class="language-javascript">const numbers = [1, 2, 3, 3, 4, 4, 5, 5, 5];
const unique = [...new Set(numbers)];
console.log(unique);  // [1, 2, 3, 4, 5]
</code></pre>
<h3>Problems with Objects and Arrays</h3>
<p>Objects have issues:</p>
<pre><code class="language-javascript">const obj = {};

// All keys become strings
obj[1] = "one";
obj[true] = "yes";
obj[{id: 1}] = "object";

console.log(Object.keys(obj));  // ['1', 'true', '[object Object]']
// Lost the original types!
</code></pre>
<p>Arrays have issues with duplicates:</p>
<pre><code class="language-javascript">const arr = [1, 2, 3, 3, 4, 4, 5];

// No built-in way to check uniqueness
console.log(arr.length);  // 7 (includes duplicates)

// Checking membership is slow
arr.includes(3);  // Linear search O(n)
</code></pre>
<hr />
<h2>Complete Practical Examples</h2>
<h3>Example 1: User Roles with Map</h3>
<pre><code class="language-javascript">const userRoles = new Map();

// Add users and their roles
userRoles.set(1, ["user", "admin"]);
userRoles.set(2, ["user"]);
userRoles.set(3, ["user", "moderator"]);

// Check role
function hasRole(userId, role) {
  const roles = userRoles.get(userId);
  return roles &amp;&amp; roles.includes(role);
}

console.log(hasRole(1, "admin"));     // true
console.log(hasRole(2, "admin"));     // false

// Update roles
userRoles.set(2, ["user", "admin"]);

// Remove user
userRoles.delete(3);

// How many users?
console.log(userRoles.size);
</code></pre>
<h3>Example 2: Unique Categories with Set</h3>
<pre><code class="language-javascript">const categories = new Set();

function addCategory(category) {
  categories.add(category);
}

function removeCategory(category) {
  categories.delete(category);
}

function listCategories() {
  return Array.from(categories);
}

// Add categories
addCategory("javascript");
addCategory("webdev");
addCategory("javascript");  // Ignored
addCategory("node.js");

console.log(listCategories());  // ['javascript', 'webdev', 'node.js']
</code></pre>
<h3>Example 3: Cache with Map</h3>
<pre><code class="language-javascript">const apiCache = new Map();
const CACHE_DURATION = 5 * 60 * 1000;  // 5 minutes

async function fetchWithCache(url) {
  // Check if cached
  if (apiCache.has(url)) {
    const cached = apiCache.get(url);
    
    if (Date.now() - cached.timestamp &lt; CACHE_DURATION) {
      console.log("From cache");
      return cached.data;
    } else {
      apiCache.delete(url);  // Expired
    }
  }
  
  // Fetch new data
  console.log("Fetching from API");
  const response = await fetch(url);
  const data = await response.json();
  
  // Cache it
  apiCache.set(url, {
    data,
    timestamp: Date.now()
  });
  
  return data;
}
</code></pre>
<h3>Example 4: Unique Visitor Tracking with Set</h3>
<pre><code class="language-javascript">const visitedPages = new Map();

function trackVisit(userId, pageId) {
  if (!visitedPages.has(pageId)) {
    visitedPages.set(pageId, new Set());
  }
  
  visitedPages.get(pageId).add(userId);
}

function getUniqueVisitors(pageId) {
  if (visitedPages.has(pageId)) {
    return visitedPages.get(pageId).size;
  }
  return 0;
}

// Track visits
trackVisit("user1", "page-a");
trackVisit("user1", "page-a");  // Same user
trackVisit("user2", "page-a");
trackVisit("user3", "page-a");

console.log(getUniqueVisitors("page-a"));  // 3 (unique users)
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Create a Map-based user store:</strong></p>
<pre><code class="language-javascript">// Create Map to store users with userId as key
// Add three users
// Find a user
// Update a user
// Delete a user
// Show total users
</code></pre>
<p><strong>2. Use Set to remove duplicates:</strong></p>
<pre><code class="language-javascript">// Given array of tags with duplicates
// Create Set from array
// Convert back to array
// Show unique tags
</code></pre>
<p><strong>3. Build a permission system with Set:</strong></p>
<pre><code class="language-javascript">// Create Set of allowed permissions
// Create function to check permission
// Test with valid and invalid permissions
</code></pre>
<p><strong>4. Cache implementation with Map:</strong></p>
<pre><code class="language-javascript">// Create cache Map
// Implement cache function that checks before computing
// Add same value twice, show it's only computed once
</code></pre>
<p><strong>5. Visitor tracking with Map and Set:</strong></p>
<pre><code class="language-javascript">// Track which users visited which pages
// Use Map for pages, Set for unique users
// Show unique visitor count per page
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Map</strong> is a collection of key-value pairs, better than objects for complex keys.</p>
</li>
<li><p><strong>Set</strong> is a collection of unique values, automatically removes duplicates.</p>
</li>
<li><p><strong>Map</strong> accepts any data type as keys: strings, numbers, objects, functions.</p>
</li>
<li><p><strong>Object</strong> converts all keys to strings or symbols.</p>
</li>
<li><p><strong>Map</strong> has a <code>.size</code> property, objects need <code>Object.keys().length</code>.</p>
</li>
<li><p><strong>Map</strong> iterates directly with <code>.forEach()</code> or <code>for...of</code>.</p>
</li>
<li><p><strong>Objects</strong> need <code>Object.keys()</code> or <code>for...in</code> loop.</p>
</li>
<li><p><strong>Map</strong> is faster for frequent additions and deletions.</p>
</li>
<li><p><strong>Map</strong> is optimized for key-value storage operations.</p>
</li>
<li><p><strong>Set</strong> automatically removes duplicate values.</p>
</li>
<li><p><strong>Array</strong> allows duplicates, Set doesn't.</p>
</li>
<li><p><strong>Set</strong> has instant membership checking with <code>.has()</code>.</p>
</li>
<li><p><strong>Array</strong> checking with <code>.includes()</code> is slower.</p>
</li>
<li><p><strong>Array</strong> has <code>.map()</code>, <code>.filter()</code>, <code>.reduce()</code> methods.</p>
</li>
<li><p><strong>Set</strong> needs spread operator <code>[...set]</code> to use array methods.</p>
</li>
<li><p><strong>Map</strong> is perfect for caching, sessions, user data.</p>
</li>
<li><p><strong>Set</strong> is perfect for unique values, permissions, tags.</p>
</li>
<li><p>Convert <strong>Array</strong> to <strong>Set</strong> with <code>new Set(array)</code> to remove duplicates.</p>
</li>
<li><p>Convert <strong>Set</strong> to <strong>Array</strong> with <code>[...set]</code> for array methods.</p>
</li>
<li><p><strong>Objects</strong> are for simple JSON data, <strong>Maps</strong> for complex key-value logic.</p>
</li>
<li><p><strong>Arrays</strong> are for lists and sequences, <strong>Sets</strong> for unique values.</p>
</li>
</ul>
<p>Map and Set are powerful tools for clean, efficient data storage.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Why Node.js is Perfect for Building Fast Web Applications
]]></title><description><![CDATA[Node.js handles thousands of requests without freezing because it doesn't wait for operations to finish. While traditional servers lock up during database queries, Node.js continues processing other r]]></description><link>https://blog.harshx.in/why-node-js-best-for-building-fast-web-apps</link><guid isPermaLink="true">https://blog.harshx.in/why-node-js-best-for-building-fast-web-apps</guid><category><![CDATA[Node.js]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 11:41:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/302ea9b1-d6e3-4894-b885-d02328808713.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p> Node.js handles thousands of requests without freezing because it doesn't wait for operations to finish. While traditional servers lock up during database queries, Node.js continues processing other requests instantly. This makes Node.js incredibly fast for I/O-heavy applications.</p>
<p>This is about understanding why Node.js is so performant and when to use it.</p>
<hr />
<h2>What Makes Node.js Fast</h2>
<p>Node.js is fast because of two key ideas:</p>
<ol>
<li>It doesn't wait for operations to finish</li>
<li>It handles many requests at the same time</li>
</ol>
<h3>The Speed Problem with Traditional Servers</h3>
<p>Traditional servers block. When processing a request:</p>
<pre><code class="language-plaintext">Request 1 arrives
      |
      v
Server reads database (takes 1 second)
      |
      v
Server sends response
      |
      v
Request 2 arrives
Server is now free
</code></pre>
<p>Request 2 waits for Request 1 to finish. The server freezes.</p>
<p>If 100 requests arrive, the server freezes 100 times.</p>
<h3>How Node.js Solves This</h3>
<p>Node.js doesn't wait. When a request needs to wait for something:</p>
<pre><code class="language-plaintext">Request 1 arrives
      |
      v
Node starts database query
(doesn't wait)
      |
      v
Request 2 arrives immediately
Node processes it
      |
      v
Request 3 arrives
Node processes it
      |
      v
Database finishes Request 1
Node sends response to client 1
</code></pre>
<p>All requests are handled. No freezing.</p>
<h3>Real Numbers</h3>
<p>Traditional server: 100 requests, each takes 1 second for database = 100 seconds total</p>
<p>Node.js server: 100 requests, all waiting on database simultaneously = 1 second total</p>
<p>Huge difference.</p>
<hr />
<h2>Non-Blocking I/O Concept</h2>
<p>Non-blocking I/O means code doesn't pause waiting for slow operations.</p>
<h3>I/O Operations</h3>
<p>I/O stands for Input/Output. Examples:</p>
<ul>
<li>Reading files from disk</li>
<li>Querying databases</li>
<li>Making HTTP requests</li>
<li>Writing to disk</li>
</ul>
<p>All are slow compared to CPU speed.</p>
<h3>Blocking I/O (Traditional)</h3>
<pre><code class="language-javascript">// Blocking: code pauses here
const data = fs.readFileSync("large-file.txt");
console.log("File read");  // Waits until file is completely read
doOtherStuff();            // Only runs AFTER file is read
</code></pre>
<p>The program freezes while reading the file. Nothing else happens.</p>
<h3>Non-Blocking I/O (Node.js)</h3>
<pre><code class="language-javascript">// Non-blocking: code continues immediately
fs.readFile("large-file.txt", (err, data) =&gt; {
  console.log("File read");  // Runs when file is done
});
console.log("Request sent");  // Runs immediately
doOtherStuff();               // Runs immediately
</code></pre>
<p>The program doesn't wait. It starts reading the file and continues with other tasks. When the file is done, a callback runs.</p>
<h3>The Real-World Impact</h3>
<p>Blocking (traditional):</p>
<pre><code class="language-plaintext">Fetch from DB (1 second) ▓▓▓▓▓▓▓▓▓▓
Idle, waiting        ▓▓▓▓▓▓▓▓▓▓
Send response        ▓
</code></pre>
<p>Non-blocking (Node.js):</p>
<pre><code class="language-plaintext">Start DB query ▓
Process next request ▓
Process another request ▓
Process another request ▓
...handle 100 requests ▓▓▓▓▓▓▓▓▓▓
All responses send when ready ▓
</code></pre>
<p>Node.js never idles. It's always doing something.</p>
<hr />
<h2>Event-Driven Architecture</h2>
<p>Node.js responds to events instead of waiting.</p>
<h3>What is Event-Driven?</h3>
<p>Instead of:</p>
<pre><code>Ask the kitchen for food
Wait, watching them cook
Food is ready
Leave
</code></pre>
<p>Event-driven is:</p>
<pre><code>Ask the kitchen for food
Get a pager number
Go sit down
Do other things
Pager buzzes when ready
Go pick up food
Leave
</code></pre>
<p>Much more efficient.</p>
<h3>How Events Work in Node.js</h3>
<pre><code class="language-javascript">// Set up listeners (waiting for events)
fs.readFile("file.txt", (err, data) =&gt; {
  console.log("File event: data ready");
});

// More code runs immediately
console.log("File reading started");
makeRequest("http://api.example.com");
queryDatabase("SELECT * FROM users");

console.log("All operations started");
</code></pre>
<p>Output:</p>
<pre><code>File reading started
All operations started
(1 second later)
File event: data ready
</code></pre>
<p>Code doesn't wait. Events trigger callbacks when ready.</p>
<h3>The Event Loop</h3>
<p>Node.js has an event loop that checks for completed operations:</p>
<pre><code class="language-plaintext">Event Loop Cycle
      |
      v
Check if database query finished
      |
      ├─ Yes → Run callback
      └─ No → Continue
      |
      v
Check if file read finished
      |
      ├─ Yes → Run callback
      └─ No → Continue
      |
      v
Check if HTTP request finished
      |
      ├─ Yes → Run callback
      └─ No → Continue
      |
      v
Loop back to start
</code></pre>
<p>The loop continuously checks what's done. When something finishes, the callback runs.</p>
<h3>Real Example: Restaurant Orders</h3>
<p>Without event-driven (blocking):</p>
<pre><code class="language-javascript">const order1 = "burger";
waitForFood(order1);  // Cook burger, wait here
serveFood(order1);    // Now take order 2

const order2 = "pizza";
waitForFood(order2);  // Cook pizza, wait here
serveFood(order2);    // Now take order 3

// Only 3 orders in 1 hour
</code></pre>
<p>With event-driven (non-blocking):</p>
<pre><code class="language-javascript">const order1 = "burger";
startCooking(order1, () =&gt; {
  serveFood(order1);  // When done, serve it
});

const order2 = "pizza";
startCooking(order2, () =&gt; {
  serveFood(order2);  // When done, serve it
});

const order3 = "fries";
startCooking(order3, () =&gt; {
  serveFood(order3);  // When done, serve it
});

// All cooking at the same time!
// 3 orders done in 1/3 the time
</code></pre>
<hr />
<h2>Single-Threaded Model Explained</h2>
<p>Node.js runs JavaScript on a single thread. But it handles multiple operations.</p>
<h3>What is a Thread?</h3>
<p>A thread is a line of execution. One thread means one line of code at a time.</p>
<pre><code class="language-plaintext">Thread 1
First instruction
    |
    v
Second instruction
    |
    v
Third instruction
</code></pre>
<p>One task at a time, in order.</p>
<h3>Single-Threaded Means</h3>
<pre><code class="language-javascript">console.log("1");
console.log("2");
console.log("3");

// Output:
// 1
// 2
// 3
</code></pre>
<p>Always in order, always one at a time.</p>
<h3>But How Does It Handle Multiple Requests?</h3>
<p>Here's the magic: while one request waits for I/O, Node.js handles other requests.</p>
<pre><code class="language-plaintext">Thread (JavaScript execution)

Request 1: console.log("Starting") ▓
           fs.readFile() ▓
Request 1 waits for file...
           (Thread handles Request 2)

Request 2: console.log("Starting") ▓
           fs.readFile() ▓
Request 2 waits for file...
           (Thread handles Request 3)

Request 3: console.log("Starting") ▓
           database.query() ▓
Request 3 waits for database...
           (Check if anything is done)

File finishes for Request 1 ▓
(Thread runs callback for Request 1)
Response sent to Request 1 ▓
</code></pre>
<p>While waiting, the thread does other work. Not true parallelism, but looks like it.</p>
<h3>Concurrency vs Parallelism</h3>
<p>Concurrency (Node.js):</p>
<pre><code class="language-plaintext">One thread, multiple tasks
Task 1: [=====&gt; wait]
Task 2:        [=====&gt; wait]
Task 3:               [=====&gt;]
        
Thread switches between them
No waiting idle time
</code></pre>
<p>Parallelism (Java, C++):</p>
<pre><code class="language-plaintext">Multiple threads, multiple tasks
Thread 1: Task 1 [=====&gt; wait]
Thread 2: Task 2 [=====&gt; wait]
Thread 3: Task 3 [=====&gt;]
        
True simultaneous execution
More CPU usage
</code></pre>
<p>Node.js uses concurrency. Cheaper than parallelism.</p>
<h3>Why Single-Threaded is Better for I/O</h3>
<p>For I/O-heavy apps, single-threaded is perfect:</p>
<ul>
<li>No context switching overhead (threads are expensive)</li>
<li>No synchronization problems (one thread, no conflicts)</li>
<li>Less memory (one thread vs many threads)</li>
<li>Simpler code (no locks or mutexes)</li>
</ul>
<p>For CPU-intensive apps, it's not ideal:</p>
<ul>
<li>Only one CPU core is used</li>
<li>Heavy calculations freeze the thread</li>
<li>Better to use multiple threads</li>
</ul>
<hr />
<h2>Blocking vs Non-Blocking Request Handling</h2>
<h3>Blocking Server (Traditional)</h3>
<pre><code class="language-plaintext">Request 1 arrives
      |
      v
Database query (1 second)
      |
      v
Response sent
      |
      v
Request 2 arrives
      |
      v
Database query (1 second)
      |
      v
Response sent
      |
      v
Request 3 arrives
      |
      v
Database query (1 second)
      |
      v
Response sent

Total time: 3 seconds for 3 requests
Server frozen during each query
</code></pre>
<h3>Non-Blocking Server (Node.js)</h3>
<pre><code class="language-plaintext">Request 1 arrives
      |
      v
Start database query (no wait)
      |
      v
Request 2 arrives (immediately)
      |
      v
Start database query (no wait)
      |
      v
Request 3 arrives (immediately)
      |
      v
Start database query (no wait)
      |
      v
(All 3 queries run simultaneously)
      |
      v
Responses sent as queries finish

Total time: 1 second for 3 requests
Server never freezes
</code></pre>
<p>Node.js handles 3 requests in 1/3 the time.</p>
<h3>Code Comparison</h3>
<p>Blocking (traditional server):</p>
<pre><code class="language-javascript">// This freezes the entire server
app.get("/users", (req, res) =&gt; {
  const users = database.query("SELECT * FROM users");  // Waits 1 second
  res.send(users);  // Only then sends response
});

// Other requests wait while this query runs
</code></pre>
<p>Non-blocking (Node.js):</p>
<pre><code class="language-javascript">// This doesn't freeze anything
app.get("/users", (req, res) =&gt; {
  database.query("SELECT * FROM users", (err, users) =&gt; {
    res.send(users);  // Sends when ready
  });
  // Function returns immediately, request is still pending
});

// Other requests are processed while query runs
</code></pre>
<hr />
<h2>Where Node.js Performs Best</h2>
<h3>Perfect For: I/O-Heavy Applications</h3>
<p>Node.js excels when dealing with lots of I/O:</p>
<pre><code class="language-plaintext">Database queries ✓ Perfect
File operations ✓ Perfect
API requests ✓ Perfect
Network I/O ✓ Perfect
Real-time updates ✓ Perfect
Streaming data ✓ Perfect
</code></pre>
<h3>Perfect For: Real-Time Applications</h3>
<p>Chat applications, notifications, live updates:</p>
<pre><code class="language-javascript">// WebSocket connection
socket.on("message", (msg) =&gt; {
  broadcast(msg);  // Send to all users instantly
});
</code></pre>
<p>Event-driven architecture is built for this.</p>
<h3>Perfect For: Microservices</h3>
<p>Small services that communicate over networks:</p>
<pre><code class="language-plaintext">User Service → Database ✓
Auth Service → Database ✓
Payment Service → External API ✓
Email Service → SMTP Server ✓

All handle many concurrent connections
</code></pre>
<h3>Not Ideal For: CPU-Intensive Work</h3>
<p>Heavy calculations, image processing, video encoding:</p>
<pre><code class="language-plaintext">Heavy computation ✗ Bad (freezes thread)
Image resizing ✗ Bad
Video encoding ✗ Bad
Complex calculations ✗ Bad

Only one core is used
</code></pre>
<p>For CPU work, use Python, Java, or C++.</p>
<h3>Best Use Cases Summary</h3>
<pre><code class="language-plaintext">Web APIs ✓ Excellent
REST services ✓ Excellent
Real-time apps ✓ Excellent
Streaming ✓ Excellent
Microservices ✓ Excellent
File servers ✓ Excellent
Chat apps ✓ Excellent
Dashboards ✓ Excellent

Video processing ✗ Not good
AI/ML training ✗ Not good
Scientific computing ✗ Not good
Image batching ✗ Not good
</code></pre>
<hr />
<h2>Real-World Companies Using Node.js</h2>
<h3>Netflix</h3>
<p>Netflix uses Node.js for:</p>
<ul>
<li>Fast API responses</li>
<li>Handling millions of concurrent users</li>
<li>Real-time recommendations</li>
</ul>
<p>Why? Non-blocking I/O handles massive traffic without freezing.</p>
<h3>Uber</h3>
<p>Uber uses Node.js for:</p>
<ul>
<li>Real-time location tracking</li>
<li>Instant ride matching</li>
<li>Scalable microservices</li>
</ul>
<p>Why? Event-driven architecture perfect for real-time updates.</p>
<h3>Slack</h3>
<p>Slack uses Node.js for:</p>
<ul>
<li>Instant messaging</li>
<li>File uploads</li>
<li>WebSocket connections</li>
</ul>
<p>Why? Handles thousands of concurrent connections efficiently.</p>
<h3>Trello</h3>
<p>Trello uses Node.js for:</p>
<ul>
<li>Real-time board updates</li>
<li>Collaborative features</li>
<li>Fast response times</li>
</ul>
<p>Why? Event-driven perfect for live collaboration.</p>
<h3>Walmart</h3>
<p>Walmart uses Node.js for:</p>
<ul>
<li>Black Friday traffic spikes</li>
<li>Mobile app API</li>
<li>Fast checkout</li>
</ul>
<p>Why? Handles sudden traffic surges without crashing.</p>
<h3>PayPal</h3>
<p>PayPal uses Node.js for:</p>
<ul>
<li>Payment processing</li>
<li>High concurrency handling</li>
<li>Microservices architecture</li>
</ul>
<p>Why? Non-blocking I/O processes transactions quickly.</p>
<h3>LinkedIn</h3>
<p>LinkedIn uses Node.js for:</p>
<ul>
<li>Mobile apps</li>
<li>Real-time notifications</li>
<li>Fast feeds</li>
</ul>
<p>Why? Single-threaded model is efficient for I/O.</p>
<h3>Why These Companies?</h3>
<p>All these companies have one thing in common: they need to handle massive concurrent requests without freezing. Node.js excels at this.</p>
<hr />
<h2>Event Loop Request Processing Visualization</h2>
<pre><code class="language-plaintext">User makes multiple requests
      |
      v
Request 1 arrives → starts DB query
Request 2 arrives → starts API call
Request 3 arrives → starts file read
      |
      v
Event Loop Cycle 1:
├─ DB query done? Yes → run callback for Request 1
├─ API call done? No
└─ File read done? No
      |
      v
Event Loop Cycle 2:
├─ API call done? Yes → run callback for Request 2
├─ File read done? No
      |
      v
Event Loop Cycle 3:
├─ File read done? Yes → run callback for Request 3
      |
      v
All responses sent to clients
      |
      v
Waiting for next requests
</code></pre>
<p>The event loop constantly checks what's finished and runs callbacks.</p>
<hr />
<h2>Performance Characteristics</h2>
<h3>Throughput (Requests Per Second)</h3>
<p>Node.js can handle thousands of concurrent connections:</p>
<pre><code class="language-plaintext">Traditional Server
Connections:  10    50    100   500   1000
Server: [OK] [OK] [SLOW] [CRASH]

Node.js Server
Connections:  10    50    100   500   1000   5000
Server:  [OK] [OK]  [OK] [OK]  [OK]  [OK]
</code></pre>
<h3>Memory Usage</h3>
<p>Node.js uses less memory per connection:</p>
<pre><code class="language-plaintext">Traditional Server: 1 thread per request
1000 requests = 1000 threads = huge memory

Node.js: 1 thread handles thousands
1000 requests = 1 thread = minimal memory
</code></pre>
<h3>Response Time Under Load</h3>
<p>As load increases:</p>
<pre><code class="language-plaintext">Traditional Server
Load increases → Response time increases linearly → Crashes

Node.js Server
Load increases → Response time stays flat → Handles more

Why? Not waiting. Handling more requests in same time.
</code></pre>
<hr />
<h2>Complete Example: Fast API</h2>
<pre><code class="language-javascript">const express = require("express");
const mysql = require("mysql2/promise");

const app = express();
app.use(express.json());

const pool = mysql.createPool({
  host: "localhost",
  user: "root",
  password: "password",
  database: "mydb",
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

// Non-blocking API endpoint
app.get("/users", async (req, res) =&gt; {
  try {
    // Don't wait with blocking code
    const [users] = await pool.query("SELECT * FROM users");
    res.json(users);  // Send when ready
  } catch (error) {
    res.status(500).json({ error: "Database error" });
  }
});

// Multiple concurrent requests handled here
app.get("/posts", async (req, res) =&gt; {
  const [posts] = await pool.query("SELECT * FROM posts");
  res.json(posts);
});

// Real-time endpoint
app.get("/live-count", (req, res) =&gt; {
  let count = 0;
  const interval = setInterval(() =&gt; {
    count++;
    if (count === 10) {
      clearInterval(interval);
      res.json({ count });
    }
  }, 100);
});

app.listen(3000, () =&gt; {
  console.log("Server running on port 3000");
  console.log("Try: curl http://localhost:3000/users");
  console.log("Try: curl http://localhost:3000/posts");
  console.log("Multiple requests handled simultaneously");
});
</code></pre>
<h3>Why This is Fast</h3>
<pre><code class="language-plaintext">Request 1: GET /users
  → Start DB query
  → Don't wait
  |
  └─→ Request 2: GET /posts arrives
      → Start DB query
      → Don't wait
      |
      └─→ Request 3: GET /live-count arrives
          → Start counting
          → Don't wait
          
Both queries run at the same time
All responses sent as they finish
Zero blocking, maximum throughput
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Compare blocking vs non-blocking:</strong></p>
<pre><code class="language-javascript">// Write blocking code that makes three database queries
// Then write non-blocking version
// Notice the difference in execution time
</code></pre>
<p><strong>2. Understand the event loop:</strong></p>
<pre><code class="language-javascript">// Write code that:
// - Starts three async operations
// - Logs when each completes
// - Shows how event loop handles them
</code></pre>
<p><strong>3. Real-time application:</strong></p>
<pre><code class="language-javascript">// Create Express server with WebSocket
// Broadcast messages to multiple clients
// Show how Node.js handles concurrent connections
</code></pre>
<p><strong>4. Measure throughput:</strong></p>
<pre><code class="language-javascript">// Create Node.js server that handles requests
// Use Apache Bench or curl in loop to test
// See how many concurrent requests it handles
// Compare with what traditional server could handle
</code></pre>
<p><strong>5. Identify use cases:</strong></p>
<pre><code class="language-javascript">// Given these projects:
// - Chat application
// - Image processing batch job
// - Stock trading API
// - Video encoding service

// Which should use Node.js? Why?
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Node.js is fast</strong> because it doesn't wait for I/O operations.</p>
</li>
<li><p><strong>Non-blocking I/O</strong> means code continues while operations complete in background.</p>
</li>
<li><p><strong>Event-driven architecture</strong> means responding to events, not waiting for completion.</p>
</li>
<li><p><strong>Single-threaded</strong> Node.js handles concurrency (many requests) not parallelism (many threads).</p>
</li>
<li><p>One request waiting doesn't freeze other requests.</p>
</li>
<li><p>The <strong>event loop</strong> constantly checks what operations are done.</p>
</li>
<li><p><strong>Blocking</strong> servers freeze. <strong>Non-blocking</strong> servers continue.</p>
</li>
<li><p>Node.js handles <strong>thousands of concurrent connections</strong> efficiently.</p>
</li>
<li><p><strong>Concurrency</strong> (switching between tasks) is cheaper than <strong>parallelism</strong> (multiple threads).</p>
</li>
<li><p>Node.js uses <strong>less memory</strong> than traditional servers (one thread vs many).</p>
</li>
<li><p><strong>Response time stays constant</strong> even as load increases (until server is saturated).</p>
</li>
<li><p>Perfect for <strong>I/O-heavy apps</strong>: APIs, real-time apps, streaming, microservices.</p>
</li>
<li><p>Not ideal for <strong>CPU-intensive</strong> work: image processing, video encoding, heavy calculations.</p>
</li>
<li><p><strong>Netflix, Uber, Slack, Walmart, PayPal</strong> all use Node.js for these reasons.</p>
</li>
<li><p>Real-time apps like <strong>chat, notifications, live updates</strong> are built for Node.js.</p>
</li>
<li><p>One Node.js server handles what would require multiple traditional servers.</p>
</li>
<li><p>The <strong>event-driven model</strong> makes code simpler and more readable.</p>
</li>
</ul>
<p>Node.js's non-blocking I/O and event-driven architecture make it perfect for modern web applications.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Destructuring in JavaScript
]]></title><description><![CDATA[Destructuring lets you extract values from objects and arrays into variables instantly. Instead of writing user.name, user.email, user.age separately, destructuring lets you do it all at once. It's a ]]></description><link>https://blog.harshx.in/destructuring-in-javascript</link><guid isPermaLink="true">https://blog.harshx.in/destructuring-in-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 11:31:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/e5d48e9d-050a-4e96-ae45-63f97740a9eb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p> Destructuring lets you extract values from objects and arrays into variables instantly. Instead of writing <code>user.name</code>, <code>user.email</code>, <code>user.age</code> separately, destructuring lets you do it all at once. It's a cleaner way to work with data.</p>
<p>This is about understanding destructuring and writing cleaner JavaScript code.</p>
<hr />
<h2>What Destructuring Means</h2>
<p>Destructuring is unpacking values from objects and arrays into separate variables.</p>
<h3>Simple Definition</h3>
<p>Destructuring means taking the values inside a container (object or array) and pulling them out into individual variables.</p>
<h3>Real Example</h3>
<p>Without destructuring:</p>
<pre><code class="language-javascript">const user = { name: "Alice", email: "alice@example.com", age: 25 };

const name = user.name;
const email = user.email;
const age = user.age;

console.log(name);   // "Alice"
console.log(email);  // "alice@example.com"
console.log(age);    // 25
</code></pre>
<p>Four lines just to extract values.</p>
<p>With destructuring:</p>
<pre><code class="language-javascript">const user = { name: "Alice", email: "alice@example.com", age: 25 };

const { name, email, age } = user;

console.log(name);   // "Alice"
console.log(email);  // "alice@example.com"
console.log(age);    // 25
</code></pre>
<p>One line. Much cleaner.</p>
<h3>The Analogy</h3>
<p>Think of unpacking a suitcase.</p>
<p>Without destructuring:</p>
<pre><code>You have a suitcase with clothes inside
You take out one shirt
You take out one pair of pants
You take out one pair of socks
You take out one jacket
(4 separate actions)
</code></pre>
<p>With destructuring:</p>
<pre><code>You have a suitcase with clothes inside
You open it and pull out all at once
(1 action, everything is organized)
</code></pre>
<p>Same result. Much more efficient.</p>
<h3>Why It Matters</h3>
<p>Destructuring:</p>
<ul>
<li>Reduces repetitive code</li>
<li>Makes code easier to read</li>
<li>Saves time</li>
<li>Reduces mistakes</li>
</ul>
<hr />
<h2>Destructuring Arrays</h2>
<p>Extract values from arrays by position.</p>
<h3>Basic Array Destructuring</h3>
<pre><code class="language-javascript">const colors = ["red", "green", "blue"];

// Without destructuring
const first = colors[0];
const second = colors[1];
const third = colors[2];

// With destructuring
const [first, second, third] = colors;

console.log(first);   // "red"
console.log(second);  // "green"
console.log(third);   // "blue"
</code></pre>
<p>The order matters. The first variable gets the first element, the second variable gets the second element, and so on.</p>
<h3>Skipping Elements</h3>
<pre><code class="language-javascript">const colors = ["red", "green", "blue", "yellow"];

// Skip green, get red and blue
const [first, , third] = colors;

console.log(first);  // "red"
console.log(third);  // "blue"
</code></pre>
<p>Use empty commas to skip elements.</p>
<h3>Rest Operator (Get Remaining Elements)</h3>
<pre><code class="language-javascript">const numbers = [1, 2, 3, 4, 5];

const [first, second, ...rest] = numbers;

console.log(first);  // 1
console.log(second); // 2
console.log(rest);   // [3, 4, 5]
</code></pre>
<p>The <code>...rest</code> operator captures all remaining elements into an array.</p>
<h3>Swapping Values</h3>
<p>Destructuring makes swapping easy:</p>
<pre><code class="language-javascript">let a = 1;
let b = 2;

console.log("Before:", a, b);  // Before: 1 2

// Swap
[a, b] = [b, a];

console.log("After:", a, b);   // After: 2 1
</code></pre>
<p>No temporary variable needed.</p>
<h3>Destructuring with Functions</h3>
<pre><code class="language-javascript">function getCoordinates() {
  return [10, 20];
}

const [x, y] = getCoordinates();

console.log(x);  // 10
console.log(y);  // 20
</code></pre>
<p>Functions return arrays. Destructure them instantly.</p>
<h3>Array Destructuring Mapping</h3>
<pre><code class="language-plaintext">Array
[10, 20, 30, 40, 50]
 |   |   |
 v   v   v
const [a, b, c] = ...
 |   |   |
 v   v   v
a=10, b=20, c=30
</code></pre>
<p>Each position in the array maps to a variable in order.</p>
<hr />
<h2>Destructuring Objects</h2>
<p>Extract values from objects by property name.</p>
<h3>Basic Object Destructuring</h3>
<pre><code class="language-javascript">const user = { name: "Alice", email: "alice@example.com", age: 25 };

// Without destructuring
const name = user.name;
const email = user.email;
const age = user.age;

// With destructuring
const { name, email, age } = user;

console.log(name);   // "Alice"
console.log(email);  // "alice@example.com"
console.log(age);    // 25
</code></pre>
<p>The property names become variables. Order doesn't matter.</p>
<h3>Selecting Specific Properties</h3>
<pre><code class="language-javascript">const user = { name: "Alice", email: "alice@example.com", age: 25, city: "NYC" };

// Only extract name and email
const { name, email } = user;

console.log(name);   // "Alice"
console.log(email);  // "alice@example.com"
// age and city are not extracted
</code></pre>
<p>Extract only what you need.</p>
<h3>Renaming Variables</h3>
<pre><code class="language-javascript">const user = { name: "Alice", email: "alice@example.com" };

// Rename email to userEmail
const { name, email: userEmail } = user;

console.log(name);      // "Alice"
console.log(userEmail); // "alice@example.com"
</code></pre>
<p>Use the colon to rename properties.</p>
<h3>Nested Object Destructuring</h3>
<pre><code class="language-javascript">const user = {
  name: "Alice",
  address: {
    city: "NYC",
    zipcode: "10001"
  }
};

// Extract nested properties
const { name, address: { city, zipcode } } = user;

console.log(name);     // "Alice"
console.log(city);     // "NYC"
console.log(zipcode);  // "10001"
</code></pre>
<p>Access nested properties with additional curly braces.</p>
<h3>Rest Operator with Objects</h3>
<pre><code class="language-javascript">const user = { name: "Alice", email: "alice@example.com", age: 25, city: "NYC" };

// Extract name, rest goes into other
const { name, ...other } = user;

console.log(name);   // "Alice"
console.log(other);  // { email: "alice@example.com", age: 25, city: "NYC" }
</code></pre>
<p>The <code>...other</code> operator captures all remaining properties.</p>
<h3>Object → Variable Extraction Visual</h3>
<pre><code class="language-plaintext">Object
{
  name: "Alice",
  email: "alice@example.com",
  age: 25
}
|
├─ name ─────→ name variable
├─ email ────→ email variable
└─ age ──────→ age variable

Result:
name = "Alice"
email = "alice@example.com"
age = 25
</code></pre>
<p>Each property name becomes a variable with the same name.</p>
<hr />
<h2>Default Values</h2>
<p>Provide fallback values if properties don't exist.</p>
<h3>Default Values in Arrays</h3>
<pre><code class="language-javascript">const colors = ["red"];

const [first, second, third = "blue"] = colors;

console.log(first);   // "red"
console.log(second);  // undefined
console.log(third);   // "blue" (default used)
</code></pre>
<p>If an element doesn't exist, use the default.</p>
<h3>Practical Array Example</h3>
<pre><code class="language-javascript">function getSettings() {
  return ["dark"];  // Only one value returned
}

const [theme, language = "en", notifications = true] = getSettings();

console.log(theme);         // "dark"
console.log(language);      // "en" (default)
console.log(notifications); // true (default)
</code></pre>
<p>Perfect for functions that return partial data.</p>
<h3>Default Values in Objects</h3>
<pre><code class="language-javascript">const user = { name: "Alice" };  // email missing

const { name, email = "noemail@example.com" } = user;

console.log(name);   // "Alice"
console.log(email);  // "noemail@example.com" (default)
</code></pre>
<p>If a property doesn't exist, use the default value.</p>
<h3>Multiple Defaults</h3>
<pre><code class="language-javascript">const settings = { theme: "dark" };

const { theme, language = "en", notifications = true, timezone = "UTC" } = settings;

console.log(theme);         // "dark"
console.log(language);      // "en"
console.log(notifications); // true
console.log(timezone);      // "UTC"
</code></pre>
<p>Every property can have a default.</p>
<h3>Default with Renamed Variables</h3>
<pre><code class="language-javascript">const user = { name: "Alice" };

const { name, email: userEmail = "no-email@example.com" } = user;

console.log(name);      // "Alice"
console.log(userEmail); // "no-email@example.com"
</code></pre>
<p>Combine renaming and defaults.</p>
<hr />
<h2>Benefits of Destructuring</h2>
<h3>Benefit 1: Less Repetitive Code</h3>
<p>Without destructuring:</p>
<pre><code class="language-javascript">const user = { name: "Alice", email: "alice@example.com", age: 25 };

function displayUser() {
  console.log(user.name);
  console.log(user.email);
  console.log(user.age);
}
</code></pre>
<p>Repeating <code>user.</code> three times.</p>
<p>With destructuring:</p>
<pre><code class="language-javascript">const user = { name: "Alice", email: "alice@example.com", age: 25 };

function displayUser() {
  const { name, email, age } = user;
  console.log(name);
  console.log(email);
  console.log(age);
}
</code></pre>
<p>Extract once, use many times.</p>
<h3>Benefit 2: Cleaner Function Parameters</h3>
<p>Without destructuring:</p>
<pre><code class="language-javascript">function createPost(post) {
  const title = post.title;
  const content = post.content;
  const author = post.author;
  
  console.log(`\({title} by \){author}`);
}

createPost({ title: "Hello", content: "World", author: "Alice" });
</code></pre>
<p>Without destructuring:</p>
<pre><code class="language-javascript">function createPost({ title, content, author }) {
  console.log(`\({title} by \){author}`);
}

createPost({ title: "Hello", content: "World", author: "Alice" });
</code></pre>
<p>The function signature shows exactly what data it needs.</p>
<h3>Benefit 3: Works with Defaults</h3>
<p>Without destructuring:</p>
<pre><code class="language-javascript">function displayUser(user) {
  const name = user.name || "Unknown";
  const age = user.age || 0;
  
  console.log(`\({name} is \){age} years old`);
}
</code></pre>
<p>Multiple lines for defaults.</p>
<p>With destructuring:</p>
<pre><code class="language-javascript">function displayUser({ name = "Unknown", age = 0 }) {
  console.log(`\({name} is \){age} years old`);
}
</code></pre>
<p>Defaults built in.</p>
<h3>Benefit 4: Easy to Add/Remove Properties</h3>
<p>Without destructuring:</p>
<pre><code class="language-javascript">const user = { name: "Alice", email: "alice@example.com", age: 25, city: "NYC" };

const name = user.name;
const email = user.email;
const age = user.age;
// city is ignored

// Add city later?
const city = user.city;  // Another line
</code></pre>
<p>Without destructuring:</p>
<pre><code class="language-javascript">const user = { name: "Alice", email: "alice@example.com", age: 25, city: "NYC" };

const { name, email, age, city } = user;  // Easy to add/remove
</code></pre>
<p>One line, easy to modify.</p>
<h3>Benefit 5: Immutability</h3>
<p>Destructuring creates new variables, not references:</p>
<pre><code class="language-javascript">const original = { name: "Alice", age: 25 };

const { name, age } = original;

name = "Bob";  // Only affects the variable, not original object
console.log(original.name);  // "Alice" (unchanged)
</code></pre>
<p>Safe from accidental mutations.</p>
<h3>Benefit 6: Clear Intent</h3>
<p>Without destructuring:</p>
<pre><code class="language-javascript">function processData(data) {
  console.log(data.username);
  console.log(data.email);
}
</code></pre>
<p>Not obvious what properties are needed.</p>
<p>With destructuring:</p>
<pre><code class="language-javascript">function processData({ username, email }) {
  console.log(username);
  console.log(email);
}
</code></pre>
<p>Crystal clear what data is required.</p>
<hr />
<h2>Before vs After Destructuring</h2>
<h3>Example 1: User Profile</h3>
<p>Before:</p>
<pre><code class="language-javascript">const user = {
  name: "Alice",
  email: "alice@example.com",
  age: 25,
  city: "NYC"
};

const name = user.name;
const email = user.email;
const age = user.age;
const city = user.city;

console.log(`\({name} is \){age} and lives in ${city}`);
console.log(`Email: ${email}`);
</code></pre>
<p>After:</p>
<pre><code class="language-javascript">const user = {
  name: "Alice",
  email: "alice@example.com",
  age: 25,
  city: "NYC"
};

const { name, email, age, city } = user;

console.log(`\({name} is \){age} and lives in ${city}`);
console.log(`Email: ${email}`);
</code></pre>
<p>Cleaner and faster to write.</p>
<h3>Example 2: API Response</h3>
<p>Before:</p>
<pre><code class="language-javascript">function handleResponse(response) {
  const status = response.status;
  const data = response.data;
  const message = response.message;
  
  if (status === 200) {
    console.log(data);
  } else {
    console.log(message);
  }
}
</code></pre>
<p>After:</p>
<pre><code class="language-javascript">function handleResponse({ status, data, message }) {
  if (status === 200) {
    console.log(data);
  } else {
    console.log(message);
  }
}
</code></pre>
<p>Shorter and clearer what the function expects.</p>
<h3>Example 3: Array from Function</h3>
<p>Before:</p>
<pre><code class="language-javascript">function getCoordinates() {
  return [10, 20];
}

const coords = getCoordinates();
const x = coords[0];
const y = coords[1];

console.log(`X: \({x}, Y: \){y}`);
</code></pre>
<p>After:</p>
<pre><code class="language-javascript">function getCoordinates() {
  return [10, 20];
}

const [x, y] = getCoordinates();

console.log(`X: \({x}, Y: \){y}`);
</code></pre>
<p>Much shorter.</p>
<h3>Example 4: React Components</h3>
<p>Before:</p>
<pre><code class="language-javascript">function UserCard(props) {
  return (
    &lt;div&gt;
      &lt;h1&gt;{props.name}&lt;/h1&gt;
      &lt;p&gt;{props.email}&lt;/p&gt;
      &lt;p&gt;{props.age}&lt;/p&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>After:</p>
<pre><code class="language-javascript">function UserCard({ name, email, age }) {
  return (
    &lt;div&gt;
      &lt;h1&gt;{name}&lt;/h1&gt;
      &lt;p&gt;{email}&lt;/p&gt;
      &lt;p&gt;{age}&lt;/p&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p>Standard pattern in React development.</p>
<hr />
<h2>Common Destructuring Patterns</h2>
<h3>Pattern 1: Function Parameters</h3>
<pre><code class="language-javascript">const user = { name: "Alice", age: 25 };

// Destructure in parameters
function greet({ name, age }) {
  console.log(`Hello \({name}, you are \){age}`);
}

greet(user);  // Hello Alice, you are 25
</code></pre>
<h3>Pattern 2: API Responses</h3>
<pre><code class="language-javascript">const response = {
  status: 200,
  data: { id: 1, name: "Product" },
  message: "Success"
};

const { status, data, message } = response;

if (status === 200) {
  console.log(data);
}
</code></pre>
<h3>Pattern 3: Loop Iteration</h3>
<pre><code class="language-javascript">const users = [
  { name: "Alice", age: 25 },
  { name: "Bob", age: 30 }
];

// Destructure in loop
users.forEach(({ name, age }) =&gt; {
  console.log(`\({name} is \){age}`);
});
</code></pre>
<h3>Pattern 4: Multiple Return Values</h3>
<pre><code class="language-javascript">function getUserInfo(id) {
  return {
    id,
    name: "Alice",
    email: "alice@example.com"
  };
}

const { name, email } = getUserInfo(1);
console.log(name, email);
</code></pre>
<h3>Pattern 5: Object Merging with Defaults</h3>
<pre><code class="language-javascript">const config = { theme: "dark" };
const defaults = { theme: "light", language: "en", timezone: "UTC" };

const { theme = defaults.theme, language = defaults.language, timezone = defaults.timezone } = config;

console.log(theme);     // "dark" (from config)
console.log(language);  // "en" (from defaults)
console.log(timezone);  // "UTC" (from defaults)
</code></pre>
<hr />
<h2>Common Mistakes</h2>
<h3>Mistake 1: Forgetting Curly Braces for Objects</h3>
<pre><code class="language-javascript">const user = { name: "Alice", age: 25 };

// Wrong - missing curly braces
const name, age = user;

// Correct
const { name, age } = user;
</code></pre>
<p>Objects need <code>{}</code>. Arrays use <code>[]</code>.</p>
<h3>Mistake 2: Wrong Brackets for Arrays</h3>
<pre><code class="language-javascript">const colors = ["red", "green", "blue"];

// Wrong - using curly braces
const { first, second } = colors;

// Correct
const [first, second] = colors;
</code></pre>
<h3>Mistake 3: Property Name Must Match</h3>
<pre><code class="language-javascript">const user = { name: "Alice", age: 25 };

// Wrong - no such property
const { firstName } = user;
console.log(firstName);  // undefined

// Correct
const { name } = user;
console.log(name);  // "Alice"
</code></pre>
<p>Property names must match (unless renaming).</p>
<h3>Mistake 4: Reassigning Without Declaration</h3>
<pre><code class="language-javascript">let name;

// Wrong - can't reassign without let/const
{ name } = { name: "Alice" };

// Correct
({ name } = { name: "Alice" });

// Or use let/const
const { name } = { name: "Alice" };
</code></pre>
<p>Need parentheses when reassigning without declaration.</p>
<hr />
<h2>Complete Practical Example</h2>
<pre><code class="language-javascript">// Sample data
const users = [
  { id: 1, name: "Alice", email: "alice@example.com", age: 25, city: "NYC" },
  { id: 2, name: "Bob", email: "bob@example.com", age: 30, city: "LA" },
  { id: 3, name: "Charlie", email: "charlie@example.com", age: 28, city: "Chicago" }
];

// Function with destructuring in parameters
function displayUserInfo({ name, email, age = "Unknown", city = "Unknown" }) {
  console.log(`\({name} (\){age}) from ${city}`);
  console.log(`Email: ${email}`);
  console.log("---");
}

// Display each user
users.forEach(displayUserInfo);

// Destructure in loop
users.forEach(({ name, age }) =&gt; {
  console.log(`\({name} is \){age} years old`);
});

// Get multiple values
const [firstUser, secondUser, ...otherUsers] = users;

console.log("First user:", firstUser.name);
console.log("Second user:", secondUser.name);
console.log("Number of other users:", otherUsers.length);

// Extract and rename
const { id: userId, name: userName } = users[0];
console.log(`User ID: \({userId}, Name: \){userName}`);

// Nested destructuring
const { id, name, address: { city: userCity = "Unknown" } = {} } = users[0];
console.log(id, name, userCity);
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Basic array destructuring:</strong></p>
<pre><code class="language-javascript">// Given array: [10, 20, 30, 40, 50]
// Extract first and third elements
// Ignore the second
// Extract remaining elements into rest variable
</code></pre>
<p><strong>2. Basic object destructuring:</strong></p>
<pre><code class="language-javascript">// Given object: { name: "Alice", age: 25, city: "NYC", country: "USA" }
// Extract name and city
// Rename country to nation
// Leave age and country unextracted
</code></pre>
<p><strong>3. Default values:</strong></p>
<pre><code class="language-javascript">// Given incomplete object: { name: "Bob" }
// Destructure with defaults for missing email, age, city
// Ensure defaults appear in console.log
</code></pre>
<p><strong>4. Function parameter destructuring:</strong></p>
<pre><code class="language-javascript">// Create function that takes { username, email, status = "active" }
// Log all three values
// Call with complete object, then partial object
</code></pre>
<p><strong>5. Real-world scenario:</strong></p>
<pre><code class="language-javascript">// Create array of products: { id, name, price, inStock = true }
// Loop through with destructuring
// Extract id and name in one line per product
// Show which are in stock using inStock default
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Destructuring</strong> is unpacking values from objects and arrays into variables.</p>
</li>
<li><p><strong>Array destructuring</strong> uses square brackets: <code>const [a, b, c] = array</code>.</p>
</li>
<li><p><strong>Object destructuring</strong> uses curly braces: <code>const { name, age } = object</code>.</p>
</li>
<li><p><strong>Order matters</strong> in arrays (position-based).</p>
</li>
<li><p><strong>Property names matter</strong> in objects (name-based).</p>
</li>
<li><p>Use <strong>commas to skip</strong> array elements: <code>const [first, , third] = array</code>.</p>
</li>
<li><p>The <strong>rest operator</strong> (<code>...</code>) captures remaining elements or properties.</p>
</li>
<li><p><strong>Default values</strong> prevent undefined: <code>const { name = "Unknown" } = obj</code>.</p>
</li>
<li><p><strong>Renaming</strong> properties: <code>const { email: userEmail } = obj</code>.</p>
</li>
<li><p><strong>Nested destructuring</strong> works with nested objects and arrays.</p>
</li>
<li><p>Destructuring <strong>reduces repetitive code</strong>.</p>
</li>
<li><p><strong>Function parameters</strong> benefit most from destructuring.</p>
</li>
<li><p>Destructuring makes <strong>intent clearer</strong> in code.</p>
</li>
<li><p><strong>Immutability</strong> is preserved with destructuring.</p>
</li>
<li><p>Destructuring works with <strong>function return values</strong>.</p>
</li>
<li><p><strong>Modern React</strong> relies heavily on destructuring.</p>
</li>
<li><p>Property names must <strong>match</strong> unless renaming.</p>
</li>
<li><p>Arrays use <code>[]</code>, objects use <code>{}</code>, don't mix them up.</p>
</li>
<li><p>Destructuring is <strong>optional</strong>, not required (but recommended).</p>
</li>
</ul>
<p>Destructuring is one of the most useful modern JavaScript features.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[What is Middleware in Express and How It Works
]]></title><description><![CDATA[Middleware is code that runs between receiving a request and sending a response. It's like a security checkpoint at an airport: every passenger passes through before boarding. Your request passes thro]]></description><link>https://blog.harshx.in/what-is-middleware-and-its-working</link><guid isPermaLink="true">https://blog.harshx.in/what-is-middleware-and-its-working</guid><category><![CDATA[Node.js]]></category><category><![CDATA[Express]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[ChaiCode]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 11:26:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/7af06e0c-5840-438e-997d-bc9eae944ea1.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Middleware is code that runs between receiving a request and sending a response. It's like a security checkpoint at an airport: every passenger passes through before boarding. Your request passes through middleware before reaching the route handler.</p>
<p>This is about understanding middleware and building better Express applications.</p>
<hr />
<h2>What is Middleware in Express?</h2>
<p>Middleware is a function that processes requests and responses.</p>
<h3>Simple Definition</h3>
<p>Middleware is a function that:</p>
<ol>
<li>Receives the request object</li>
<li>Does something with it</li>
<li>Either sends a response or passes control to the next middleware</li>
</ol>
<h3>Real Example</h3>
<p>When you visit a website:</p>
<pre><code class="language-plaintext">User makes request
      |
      v
Middleware 1 checks if logged in
      |
      v
Middleware 2 validates the request
      |
      v
Middleware 3 logs the request
      |
      v
Route handler processes it
      |
      v
Response is sent
</code></pre>
<p>The request goes through several checkpoints before the actual route handler.</p>
<h3>The Checkpoint Analogy</h3>
<p>Think of middleware like checkpoints at an airport:</p>
<pre><code class="language-plaintext">Passenger enters airport
      |
      v
Checkpoint 1: Check ticket
      |
      v
Checkpoint 2: Security scan
      |
      v
Checkpoint 3: Passport check
      |
      v
Board the plane
</code></pre>
<p>Each checkpoint can:</p>
<ul>
<li>Allow you through (call <code>next()</code>)</li>
<li>Stop you (send a response)</li>
<li>Do something as you pass (check ticket, scan bag)</li>
</ul>
<p>Express middleware works the same way.</p>
<h3>Basic Middleware Function</h3>
<pre><code class="language-javascript">function myMiddleware(req, res, next) {
  // req = incoming request
  // res = response to send
  // next = function to call to move to next middleware
  
  console.log("Request received");
  next();  // Pass to next middleware
}

app.use(myMiddleware);
</code></pre>
<p>All middleware functions have this signature: <code>(req, res, next)</code>.</p>
<hr />
<h2>Where Middleware Sits in Request Lifecycle</h2>
<h3>The Complete Request Flow</h3>
<pre><code class="language-plaintext">Client sends HTTP request
      |
      v
Request arrives at Express
      |
      v
Middleware 1 runs
      |
      v
Middleware 2 runs
      |
      v
Middleware 3 runs
      |
      v
Route handler runs
      |
      v
Response is created
      |
      v
Response sent to client
      |
      v
Client receives response
</code></pre>
<p>Middleware runs before the route handler. The route handler is the final step.</p>
<h3>Request Pipeline</h3>
<p>Imagine a factory assembly line:</p>
<pre><code class="language-plaintext">Raw materials (request)
      |
      v
Station 1: Clean (middleware 1)
      |
      v
Station 2: Paint (middleware 2)
      |
      v
Station 3: Inspect (middleware 3)
      |
      v
Station 4: Package (route handler)
      |
      v
Finished product (response)
</code></pre>
<p>Each station modifies or inspects. The final station packages everything.</p>
<h3>Code Example</h3>
<pre><code class="language-javascript">const express = require("express");
const app = express();

// Middleware 1
app.use((req, res, next) =&gt; {
  console.log("Middleware 1: Request started at", new Date());
  next();  // Move to next middleware
});

// Middleware 2
app.use((req, res, next) =&gt; {
  console.log("Middleware 2: Processing request");
  next();  // Move to next middleware
});

// Route handler
app.get("/", (req, res) =&gt; {
  console.log("Route handler: Sending response");
  res.send("Hello World");
});

app.listen(3000);
</code></pre>
<p>Order of execution:</p>
<pre><code>Request to /
      |
      v
Middleware 1 runs: "Request started..."
      |
      v
Middleware 2 runs: "Processing request"
      |
      v
Route handler runs: "Sending response"
      |
      v
Response sent: "Hello World"
</code></pre>
<hr />
<h2>Types of Middleware</h2>
<h3>Type 1: Application-Level Middleware</h3>
<p>Runs for every request to your application.</p>
<pre><code class="language-javascript">// Applies to every request
app.use((req, res, next) =&gt; {
  console.log("This runs for every request");
  next();
});
</code></pre>
<h3>Type 2: Router-Level Middleware</h3>
<p>Runs only for specific routes.</p>
<pre><code class="language-javascript">// Applies only to /api routes
app.use("/api", (req, res, next) =&gt; {
  console.log("This only runs for /api routes");
  next();
});
</code></pre>
<h3>Type 3: Built-in Middleware</h3>
<p>Express provides middleware for common tasks.</p>
<pre><code class="language-javascript">// Parse JSON bodies
app.use(express.json());

// Parse form data
app.use(express.urlencoded({ extended: true }));

// Serve static files
app.use(express.static("public"));
</code></pre>
<h3>Type 4: Error-Handling Middleware</h3>
<p>Catches errors from other middleware.</p>
<pre><code class="language-javascript">// Must have 4 parameters (err, req, res, next)
app.use((err, req, res, next) =&gt; {
  console.log("Error occurred:", err.message);
  res.status(500).json({ error: "Something went wrong" });
});
</code></pre>
<p>Error handlers must be defined last.</p>
<hr />
<h2>Application-Level Middleware</h2>
<p>Runs for all requests.</p>
<h3>Basic Application Middleware</h3>
<pre><code class="language-javascript">app.use((req, res, next) =&gt; {
  console.log("Running for every request");
  next();
});

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

app.get("/about", (req, res) =&gt; {
  res.send("About");
});
</code></pre>
<p>Both GET requests pass through the middleware.</p>
<h3>Multiple Application Middleware</h3>
<pre><code class="language-javascript">// Middleware 1
app.use((req, res, next) =&gt; {
  console.log("Middleware 1");
  next();
});

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

// Middleware 3
app.use((req, res, next) =&gt; {
  console.log("Middleware 3");
  next();
});

app.get("/", (req, res) =&gt; {
  console.log("Route handler");
  res.send("Done");
});
</code></pre>
<p>Execution order:</p>
<pre><code>Middleware 1
Middleware 2
Middleware 3
Route handler
</code></pre>
<h3>Conditional Application Middleware</h3>
<pre><code class="language-javascript">// Only for GET requests
app.use((req, res, next) =&gt; {
  if (req.method === "GET") {
    console.log("This is a GET request");
  }
  next();
});

// Only for specific paths
app.use((req, res, next) =&gt; {
  if (req.path.startsWith("/admin")) {
    console.log("Admin route accessed");
  }
  next();
});
</code></pre>
<hr />
<h2>Router-Level Middleware</h2>
<p>Runs only for specific routes.</p>
<h3>Basic Router Middleware</h3>
<pre><code class="language-javascript">// Applies only to /admin routes
app.use("/admin", (req, res, next) =&gt; {
  console.log("Admin route accessed");
  next();
});

app.get("/admin/dashboard", (req, res) =&gt; {
  res.send("Admin Dashboard");
});

app.get("/admin/users", (req, res) =&gt; {
  res.send("User List");
});

// This route doesn't go through the middleware
app.get("/", (req, res) =&gt; {
  res.send("Home");
});
</code></pre>
<p>The middleware only runs for requests starting with <code>/admin</code>.</p>
<h3>Multiple Router Middleware</h3>
<pre><code class="language-javascript">// First middleware
app.use("/api", (req, res, next) =&gt; {
  console.log("API request received");
  next();
});

// Second middleware
app.use("/api", (req, res, next) =&gt; {
  console.log("Processing API request");
  next();
});

app.get("/api/users", (req, res) =&gt; {
  res.send("Users");
});
</code></pre>
<p>Both middlewares run for <code>/api/users</code> in order.</p>
<h3>Nested Routes with Middleware</h3>
<pre><code class="language-javascript">// Auth middleware only for protected routes
app.use("/api/admin", (req, res, next) =&gt; {
  console.log("Checking authentication");
  next();
});

app.get("/api/admin/stats", (req, res) =&gt; {
  res.send("Admin stats");
});

app.get("/api/public/posts", (req, res) =&gt; {
  res.send("Public posts");
});
</code></pre>
<p><code>/api/admin/stats</code> passes through middleware. <code>/api/public/posts</code> doesn't.</p>
<hr />
<h2>Built-in Middleware</h2>
<p>Express provides common middleware.</p>
<h3>JSON Parser</h3>
<pre><code class="language-javascript">app.use(express.json());

app.post("/data", (req, res) =&gt; {
  console.log(req.body);  // Parsed JSON available
  res.send("Data received");
});
</code></pre>
<p>Automatically parses JSON request bodies.</p>
<h3>Form Data Parser</h3>
<pre><code class="language-javascript">app.use(express.urlencoded({ extended: true }));

app.post("/form", (req, res) =&gt; {
  console.log(req.body);  // Form data available
  res.send("Form received");
});
</code></pre>
<p>Parses form submissions.</p>
<h3>Static File Serving</h3>
<pre><code class="language-javascript">app.use(express.static("public"));

// Now http://localhost:3000/style.css serves public/style.css
// And http://localhost:3000/index.html serves public/index.html
</code></pre>
<p>Serves files from a directory.</p>
<h3>Static with Path Prefix</h3>
<pre><code class="language-javascript">app.use("/static", express.static("public"));

// Now http://localhost:3000/static/style.css serves public/style.css
</code></pre>
<p>Serve static files under a specific path.</p>
<hr />
<h2>The Role of next()</h2>
<p><code>next()</code> is crucial. It tells Express to move to the next middleware.</p>
<h3>Without next()</h3>
<pre><code class="language-javascript">app.use((req, res, next) =&gt; {
  console.log("Middleware running");
  // Forgot to call next()
});

app.get("/", (req, res) =&gt; {
  res.send("Home");  // This never runs
});
</code></pre>
<p>The request hangs. The route handler never runs.</p>
<h3>With next()</h3>
<pre><code class="language-javascript">app.use((req, res, next) =&gt; {
  console.log("Middleware running");
  next();  // Pass to next middleware
});

app.get("/", (req, res) =&gt; {
  res.send("Home");  // Now this runs
});
</code></pre>
<p>The request moves forward. The route handler runs.</p>
<h3>Sending Response Instead of next()</h3>
<pre><code class="language-javascript">app.use((req, res, next) =&gt; {
  if (!isAuthenticated(req)) {
    res.status(401).json({ error: "Not authenticated" });
    return;  // Stop here, don't call next()
  }
  next();  // Continue if authenticated
});

app.get("/protected", (req, res) =&gt; {
  res.send("Protected content");
});
</code></pre>
<p>If authentication fails, send response. Otherwise, continue.</p>
<h3>next() with Errors</h3>
<pre><code class="language-javascript">app.use((req, res, next) =&gt; {
  try {
    // Some operation
    JSON.parse("invalid json");
    next();
  } catch (error) {
    next(error);  // Pass error to error handler
  }
});

// Error handler (4 parameters)
app.use((err, req, res, next) =&gt; {
  console.log("Error:", err.message);
  res.status(500).send("Error occurred");
});
</code></pre>
<p>Pass errors to error handlers with <code>next(error)</code>.</p>
<hr />
<h2>Middleware Execution Order</h2>
<p>Middleware runs in the order it's defined.</p>
<h3>Definition Order Matters</h3>
<pre><code class="language-javascript">// This runs first
app.use((req, res, next) =&gt; {
  console.log("First");
  next();
});

// This runs second
app.use((req, res, next) =&gt; {
  console.log("Second");
  next();
});

// This runs third
app.use((req, res, next) =&gt; {
  console.log("Third");
  next();
});

app.get("/", (req, res) =&gt; {
  console.log("Route handler");
  res.send("Done");
});
</code></pre>
<p>Output:</p>
<pre><code>First
Second
Third
Route handler
</code></pre>
<h3>Changing Order</h3>
<pre><code class="language-javascript">app.use((req, res, next) =&gt; {
  console.log("A");
  next();
});

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

app.use((req, res, next) =&gt; {
  console.log("B");  // This is defined AFTER the route
  next();
});
</code></pre>
<p>Output for GET /:</p>
<pre><code>A
(No B - defined after route)
</code></pre>
<p>Middleware defined after a route won't run for that route.</p>
<h3>Route-Specific Order</h3>
<pre><code class="language-javascript">// Runs for all /admin routes
app.use("/admin", (req, res, next) =&gt; {
  console.log("Admin middleware");
  next();
});

app.get("/admin/users", (req, res) =&gt; {
  res.send("Users");
});

// Global middleware defined after still runs first
app.use((req, res, next) =&gt; {
  console.log("Global middleware");
  next();
});
</code></pre>
<p>Global middleware defined before route-specific middleware runs first.</p>
<hr />
<h2>Request → Middleware → Route Handler Flow</h2>
<pre><code class="language-plaintext">HTTP Request arrives
      |
      v
Express receives request
      |
      v
Global middleware 1 executes
  (can access req, res)
  (can modify request)
  |
  ├─ Call next() → continue
  └─ Send response → stop here
      |
      v
Global middleware 2 executes
      |
      ├─ Call next() → continue
      └─ Send response → stop here
      |
      v
Route-specific middleware executes
      |
      ├─ Call next() → continue
      └─ Send response → stop here
      |
      v
Route handler executes
      |
      ├─ Send response → stop here
      └─ Call next() → (if defined)
      |
      v
Response sent to client
      |
      v
Client receives response
</code></pre>
<hr />
<h2>Real-World Example: Logging Middleware</h2>
<p>Log every request.</p>
<pre><code class="language-javascript">const express = require("express");
const app = express();

// Logging middleware
app.use((req, res, next) =&gt; {
  const timestamp = new Date().toISOString();
  console.log(`[\({timestamp}] \){req.method} ${req.path}`);
  next();
});

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

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

app.listen(3000, () =&gt; {
  console.log("Server running");
});
</code></pre>
<p>Output when accessing routes:</p>
<pre><code>[2026-05-04T10:30:45.123Z] GET /
[2026-05-04T10:30:50.456Z] GET /about
</code></pre>
<h3>Enhanced Logging Middleware</h3>
<pre><code class="language-javascript">app.use((req, res, next) =&gt; {
  const start = Date.now();
  
  // Log when request ends
  res.on("finish", () =&gt; {
    const duration = Date.now() - start;
    console.log(
      `\({req.method} \){req.path} - \({res.statusCode} - \){duration}ms`
    );
  });
  
  next();
});
</code></pre>
<p>Logs request duration too.</p>
<hr />
<h2>Real-World Example: Authentication Middleware</h2>
<p>Protect routes from unauthorized access.</p>
<pre><code class="language-javascript">const express = require("express");
const app = express();

// Authentication middleware
function authMiddleware(req, res, next) {
  const token = req.headers.authorization;
  
  if (!token) {
    return res.status(401).json({ error: "No token provided" });
  }
  
  if (token === "Bearer valid-token-123") {
    req.user = { id: 1, name: "Alice" };
    next();
  } else {
    res.status(401).json({ error: "Invalid token" });
  }
}

// Public route
app.get("/", (req, res) =&gt; {
  res.send("Welcome");
});

// Protected route (use middleware)
app.get("/profile", authMiddleware, (req, res) =&gt; {
  res.send(`Hello ${req.user.name}`);
});

app.listen(3000);
</code></pre>
<p>Test without token:</p>
<pre><code class="language-bash">curl http://localhost:3000/profile
# Error: No token provided
</code></pre>
<p>Test with token:</p>
<pre><code class="language-bash">curl -H "Authorization: Bearer valid-token-123" http://localhost:3000/profile
# Hello Alice
</code></pre>
<h3>Protecting Multiple Routes</h3>
<pre><code class="language-javascript">// Apply middleware to all /api routes
app.use("/api", authMiddleware);

app.get("/api/users", (req, res) =&gt; {
  res.send("Users list");
});

app.get("/api/posts", (req, res) =&gt; {
  res.send("Posts list");
});

// This route is unprotected
app.get("/public", (req, res) =&gt; {
  res.send("Public data");
});
</code></pre>
<p>All <code>/api</code> routes require authentication. <code>/public</code> doesn't.</p>
<hr />
<h2>Real-World Example: Request Validation Middleware</h2>
<p>Validate request data before processing.</p>
<pre><code class="language-javascript">const express = require("express");
const app = express();
app.use(express.json());

// Validation middleware
function validateEmail(req, res, next) {
  const email = req.body.email;
  
  if (!email) {
    return res.status(400).json({ error: "Email is required" });
  }
  
  if (!email.includes("@")) {
    return res.status(400).json({ error: "Invalid email format" });
  }
  
  next();
}

app.post("/signup", validateEmail, (req, res) =&gt; {
  const email = req.body.email;
  res.json({ message: `Signed up with ${email}` });
});

app.listen(3000);
</code></pre>
<p>Test with valid email:</p>
<pre><code class="language-bash">curl -X POST http://localhost:3000/signup \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com"}'
# Signed up with alice@example.com
</code></pre>
<p>Test with invalid email:</p>
<pre><code class="language-bash">curl -X POST http://localhost:3000/signup \
  -H "Content-Type: application/json" \
  -d '{"email":"invalid"}'
# Invalid email format
</code></pre>
<p>Test without email:</p>
<pre><code class="language-bash">curl -X POST http://localhost:3000/signup \
  -H "Content-Type: application/json" \
  -d '{}'
# Email is required
</code></pre>
<h3>Multiple Validations</h3>
<pre><code class="language-javascript">function validateName(req, res, next) {
  if (!req.body.name || req.body.name.length &lt; 2) {
    return res.status(400).json({ error: "Name must be at least 2 characters" });
  }
  next();
}

function validateEmail(req, res, next) {
  if (!req.body.email || !req.body.email.includes("@")) {
    return res.status(400).json({ error: "Invalid email" });
  }
  next();
}

app.post("/signup", validateName, validateEmail, (req, res) =&gt; {
  res.json({ message: "Signup successful" });
});
</code></pre>
<p>Both validations run before the route handler.</p>
<hr />
<h2>Multiple Middleware Execution Chain</h2>
<pre><code class="language-plaintext">Request arrives
      |
      v
Middleware 1: Logging
  console.log("Request started")
  |
  ├─ next() called
  |
  v
Middleware 2: Authentication
  Check token
  |
  ├─ Token valid: next()
  ├─ Token invalid: send 401 error (stop)
  |
  v
Middleware 3: Request Validation
  Validate data
  |
  ├─ Data valid: next()
  ├─ Data invalid: send 400 error (stop)
  |
  v
Middleware 4: Add Timestamp
  req.timestamp = Date.now()
  |
  ├─ next() called
  |
  v
Route Handler
  Process request
  Send response
  |
  v
Response sent to client
</code></pre>
<p>Each middleware runs in order. If any middleware sends a response, the chain stops.</p>
<hr />
<h2>Complete Practical Example</h2>
<pre><code class="language-javascript">const express = require("express");
const app = express();
app.use(express.json());

// Middleware 1: Logging
app.use((req, res, next) =&gt; {
  const timestamp = new Date().toISOString();
  console.log(`[\({timestamp}] \){req.method} ${req.path}`);
  next();
});

// Middleware 2: Authentication
function authenticate(req, res, next) {
  const token = req.headers.authorization?.split(" ")[1];
  
  if (!token) {
    return res.status(401).json({ error: "No token" });
  }
  
  if (token === "valid-token") {
    req.user = { id: 1, name: "Alice" };
    next();
  } else {
    res.status(401).json({ error: "Invalid token" });
  }
}

// Middleware 3: Request validation
function validateRequest(req, res, next) {
  if (!req.body.email) {
    return res.status(400).json({ error: "Email required" });
  }
  
  if (!req.body.email.includes("@")) {
    return res.status(400).json({ error: "Invalid email" });
  }
  
  next();
}

// Public route (only logging)
app.get("/", (req, res) =&gt; {
  res.send("Home");
});

// Protected route (logging + authentication)
app.get("/profile", authenticate, (req, res) =&gt; {
  res.json({ message: `Hello ${req.user.name}` });
});

// Protected with validation (logging + authentication + validation)
app.post("/update-email", authenticate, validateRequest, (req, res) =&gt; {
  res.json({ message: `Email updated to ${req.body.email}` });
});

// Error handler
app.use((err, req, res, next) =&gt; {
  console.log("Error:", err.message);
  res.status(500).json({ error: "Server error" });
});

app.listen(3000, () =&gt; {
  console.log("Server running on http://localhost:3000");
});
</code></pre>
<p>Test:</p>
<pre><code class="language-bash"># Public route (no authentication needed)
curl http://localhost:3000/
# Home

# Protected route without token
curl http://localhost:3000/profile
# No token

# Protected route with token
curl -H "Authorization: Bearer valid-token" http://localhost:3000/profile
# Hello Alice

# Update email without token
curl -X POST http://localhost:3000/update-email \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com"}'
# No token

# Update email with token
curl -X POST http://localhost:3000/update-email \
  -H "Authorization: Bearer valid-token" \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com"}'
# Email updated to alice@example.com
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Create a logging middleware:</strong></p>
<pre><code class="language-javascript">// Log every request with timestamp, method, and path
// Must call next() to continue
// Apply to all routes
</code></pre>
<p><strong>2. Build an authentication middleware:</strong></p>
<pre><code class="language-javascript">// Check Authorization header for token
// If no token, send 401 error
// If valid token, set req.user and call next()
// Protect one route with it
</code></pre>
<p><strong>3. Create request validation middleware:</strong></p>
<pre><code class="language-javascript">// Validate req.body.name (required, min 2 chars)
// Validate req.body.email (required, contains @)
// Return 400 error if invalid
// Use on a POST route
</code></pre>
<p><strong>4. Chain multiple middleware:</strong></p>
<pre><code class="language-javascript">// Create logging → authentication → validation chain
// POST route should require all three
// GET route should only require logging
// Test both routes
</code></pre>
<p><strong>5. Create route-specific middleware:</strong></p>
<pre><code class="language-javascript">// Create /api/admin routes protected by authentication
// Create /api/public routes without protection
// Show how same app has protected and public routes
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Middleware</strong> is code that runs between receiving a request and sending a response.</p>
</li>
<li><p>Middleware sits in the request pipeline: request → middleware → handler → response.</p>
</li>
<li><p>Every middleware function takes three parameters: <code>req</code>, <code>res</code>, and <code>next</code>.</p>
</li>
<li><p><code>next()</code> passes control to the next middleware in the chain.</p>
</li>
<li><p>If middleware sends a response, the chain stops (don't call <code>next()</code>).</p>
</li>
<li><p><strong>Application-level middleware</strong> runs for all requests using <code>app.use()</code>.</p>
</li>
<li><p><strong>Router-level middleware</strong> runs only for specific paths using <code>app.use("/path", ...)</code>.</p>
</li>
<li><p><strong>Built-in middleware</strong> includes <code>express.json()</code>, <code>express.urlencoded()</code>, and <code>express.static()</code>.</p>
</li>
<li><p><strong>Error-handling middleware</strong> has four parameters: <code>(err, req, res, next)</code>.</p>
</li>
<li><p>Middleware runs in the order it's defined.</p>
</li>
<li><p>Middleware defined before a route affects that route.</p>
</li>
<li><p>Middleware defined after a route doesn't affect that route.</p>
</li>
<li><p><strong>Logging middleware</strong> tracks all incoming requests.</p>
</li>
<li><p><strong>Authentication middleware</strong> protects routes from unauthorized access.</p>
</li>
<li><p><strong>Validation middleware</strong> checks request data before processing.</p>
</li>
<li><p>Multiple middleware can be applied to a single route.</p>
</li>
<li><p>Middleware can modify the request object (add properties like <code>req.user</code>).</p>
</li>
<li><p>Use conditional logic in middleware to run code based on request properties.</p>
</li>
</ul>
<p>Middleware is the foundation of building scalable Express applications.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[JavaScript Promises Explained for Beginners
]]></title><description><![CDATA[Promises are how JavaScript handles operations that take time. Instead of freezing your code waiting for a result, a promise says "I'll get back to you later." This makes your code responsive and easi]]></description><link>https://blog.harshx.in/javascript-promises-for-beginners</link><guid isPermaLink="true">https://blog.harshx.in/javascript-promises-for-beginners</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 11:23:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/9a928798-d983-4318-a6e1-0af34a40ac6e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Promises are how JavaScript handles operations that take time. Instead of freezing your code waiting for a result, a promise says "I'll get back to you later." This makes your code responsive and easier to read.</p>
<p>This is about understanding promises and writing better asynchronous JavaScript.</p>
<hr />
<h2>What Problem Do Promises Solve?</h2>
<p>JavaScript runs one line at a time. But some operations take time: fetching data, reading files, database queries.</p>
<h3>The Blocking Problem</h3>
<p>Without promises, you'd write code that waits:</p>
<pre><code class="language-javascript">// This would freeze everything
const data = getDataFromServer();  // Takes 2 seconds
console.log(data);  // Waits 2 seconds before running
doOtherStuff();     // Waits 4 seconds total
</code></pre>
<p>The entire program stops. Nothing else happens. This is bad for user experience.</p>
<h3>Real Example: Restaurant</h3>
<p>Think of ordering food at a restaurant.</p>
<p>The old way (blocking):</p>
<pre><code>1. Place order
2. Stand at counter
3. Stare at kitchen
4. Wait (30 minutes)
5. Finally eat
</code></pre>
<p>You're blocked. You can't do anything else.</p>
<p>The promise way (non-blocking):</p>
<pre><code>1. Place order
2. Get pager number
3. Go sit down
4. Do other things
5. Pager buzzes when food is ready
6. Pick it up and eat
</code></pre>
<p>You're not blocked. The pager is like a promise. It tells you "I'll notify you when your order is ready."</p>
<h3>The Callback Approach</h3>
<p>Before promises, developers used callbacks:</p>
<pre><code class="language-javascript">getDataFromServer(function(data) {
  console.log(data);
  doOtherStuff();
});

// Code continues here (non-blocking)
</code></pre>
<p>This works, but leads to "callback hell":</p>
<pre><code class="language-javascript">getUser(1, function(user) {
  getPostsForUser(user.id, function(posts) {
    getCommentsForPost(posts[0].id, function(comments) {
      getAuthorForComment(comments[0].id, function(author) {
        console.log(author.name);
        // 4 levels deep - hard to read
      });
    });
  });
});
</code></pre>
<h3>What Promises Solve</h3>
<p>Promises make asynchronous code readable:</p>
<pre><code class="language-javascript">// Much cleaner
const user = await getUser(1);
const posts = await getPostsForUser(user.id);
const comments = await getCommentsForPost(posts[0].id);
const author = await getAuthorForComment(comments[0].id);
console.log(author.name);
</code></pre>
<p>Same logic. Way more readable.</p>
<hr />
<h2>Understanding Promises as Future Values</h2>
<p>A promise is an object that represents a value that doesn't exist yet.</p>
<h3>Simple Analogy</h3>
<p>Imagine ordering a birthday cake from a bakery.</p>
<p>The bakery gives you a receipt (the promise). The receipt doesn't contain the cake yet. But it promises:</p>
<ul>
<li>Eventually, you'll get a cake</li>
<li>Or the bakery will tell you they ran out (rejection)</li>
</ul>
<p>You can:</p>
<ul>
<li>Wait for the receipt to become the cake (<code>.then()</code>)</li>
<li>Plan what to do with the cake (chain operations)</li>
<li>Handle the "ran out of cake" situation (<code>.catch()</code>)</li>
</ul>
<p>The receipt is like a promise. It's not the cake, but it represents the future cake.</p>
<h3>Promise Definition</h3>
<p>A promise is an object that represents:</p>
<ul>
<li>A value that doesn't exist yet</li>
<li>But will exist in the future (or will fail)</li>
</ul>
<pre><code class="language-javascript">const promise = new Promise((resolve, reject) =&gt; {
  // Operation that takes time
  setTimeout(() =&gt; {
    resolve("Done!");  // Success - provide the value
  }, 1000);
});

console.log(promise);  // Promise object (not "Done!" yet)

promise.then((result) =&gt; {
  console.log(result);  // "Done!" (after 1 second)
});
</code></pre>
<p>The promise is created instantly. But the result arrives later.</p>
<hr />
<h2>Promise States</h2>
<p>A promise has three states:</p>
<h3>State 1: Pending</h3>
<pre><code class="language-plaintext">Promise created
      |
      v
Waiting for operation to complete
      |
      v
State: PENDING
</code></pre>
<p>The promise is waiting. The operation hasn't finished yet.</p>
<pre><code class="language-javascript">const promise = new Promise((resolve, reject) =&gt; {
  // At this point, promise is PENDING
  // Operation hasn't finished
  setTimeout(() =&gt; {
    resolve("Done!");
  }, 1000);
});

// Here, promise is still PENDING
console.log(promise);  // Promise { &lt;pending&gt; }
</code></pre>
<h3>State 2: Fulfilled</h3>
<pre><code class="language-plaintext">Operation completes successfully
      |
      v
resolve() is called
      |
      v
State: FULFILLED
Value is now available
</code></pre>
<p>The operation succeeded. The promise has a value.</p>
<pre><code class="language-javascript">const promise = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; {
    resolve("Success!");  // Call resolve()
  }, 1000);
});

promise.then((value) =&gt; {
  console.log(value);  // "Success!"
});
</code></pre>
<h3>State 3: Rejected</h3>
<pre><code class="language-plaintext">Operation fails
      |
      v
reject() is called
      |
      v
State: REJECTED
Error is available
</code></pre>
<p>The operation failed. The promise has an error.</p>
<pre><code class="language-javascript">const promise = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; {
    reject("Something went wrong!");  // Call reject()
  }, 1000);
});

promise.catch((error) =&gt; {
  console.log(error);  // "Something went wrong!"
});
</code></pre>
<h3>State Transitions</h3>
<pre><code class="language-plaintext">PENDING
  |
  ├─ Operation succeeds → resolve() → FULFILLED
  |
  └─ Operation fails → reject() → REJECTED
</code></pre>
<p>A promise starts pending. Then it moves to fulfilled or rejected. Never both. Never back to pending.</p>
<h3>Key Rule: Promises are Immutable</h3>
<p>Once a promise is fulfilled or rejected, it can't change:</p>
<pre><code class="language-javascript">const promise = new Promise((resolve, reject) =&gt; {
  resolve("First");
  resolve("Second");  // Ignored
  reject("Error");    // Ignored
});

promise.then((value) =&gt; {
  console.log(value);  // "First" only
});
</code></pre>
<p>Only the first <code>resolve()</code> or <code>reject()</code> matters. The rest are ignored.</p>
<hr />
<h2>Promise Lifecycle Diagram</h2>
<pre><code class="language-plaintext">Promise Created
      |
      v
Promise is PENDING
(Operation running in background)
      |
      ├─ Success Path        OR        Failure Path
      |                                  |
      v                                  v
   resolve("value")                   reject("error")
      |                                  |
      v                                  v
  FULFILLED                           REJECTED
  (Value ready)                       (Error ready)
      |                                  |
      v                                  v
 .then(callback)                    .catch(callback)
      |                                  |
      v                                  v
  Handler runs                      Handler runs
  (with value)                      (with error)
</code></pre>
<hr />
<h2>Creating Promises</h2>
<h3>Creating a Promise Manually</h3>
<pre><code class="language-javascript">const promise = new Promise((resolve, reject) =&gt; {
  // resolve and reject are functions
  // Call resolve(value) when successful
  // Call reject(error) when failed
});
</code></pre>
<h3>Simple Example: Timer Promise</h3>
<pre><code class="language-javascript">const delayPromise = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; {
    resolve("Done waiting!");
  }, 2000);
});

console.log("Start");
delayPromise.then((message) =&gt; {
  console.log(message);
});
console.log("End");

// Output:
// Start
// End
// (2 seconds later)
// Done waiting!
</code></pre>
<p>The code doesn't wait for the promise. It continues. After 2 seconds, the handler runs.</p>
<h3>Example: Random Success or Failure</h3>
<pre><code class="language-javascript">const randomPromise = new Promise((resolve, reject) =&gt; {
  const random = Math.random();
  
  if (random &gt; 0.5) {
    resolve("Lucky!");
  } else {
    reject("Unlucky!");
  }
});

randomPromise
  .then((message) =&gt; {
    console.log("Success:", message);
  })
  .catch((error) =&gt; {
    console.log("Error:", error);
  });
</code></pre>
<p>Sometimes it succeeds. Sometimes it fails.</p>
<hr />
<h2>Handling Success and Failure</h2>
<h3>The .then() Method</h3>
<p><code>.then()</code> runs when the promise is fulfilled:</p>
<pre><code class="language-javascript">promise.then((value) =&gt; {
  console.log("Promise succeeded:", value);
});
</code></pre>
<p>The callback receives the value from <code>resolve()</code>.</p>
<h3>The .catch() Method</h3>
<p><code>.catch()</code> runs when the promise is rejected:</p>
<pre><code class="language-javascript">promise.catch((error) =&gt; {
  console.log("Promise failed:", error);
});
</code></pre>
<p>The callback receives the error from <code>reject()</code>.</p>
<h3>Both Together</h3>
<pre><code class="language-javascript">const promise = new Promise((resolve, reject) =&gt; {
  const success = Math.random() &gt; 0.5;
  
  if (success) {
    resolve("It worked!");
  } else {
    reject("It failed!");
  }
});

promise
  .then((value) =&gt; {
    console.log("Success:", value);
  })
  .catch((error) =&gt; {
    console.log("Error:", error);
  });
</code></pre>
<p>One or the other will run. Never both.</p>
<h3>Real Example: Fetching Data</h3>
<pre><code class="language-javascript">const fetchUserData = new Promise((resolve, reject) =&gt; {
  // Simulate API call
  setTimeout(() =&gt; {
    const success = Math.random() &gt; 0.2;
    
    if (success) {
      const user = { id: 1, name: "Alice" };
      resolve(user);
    } else {
      reject("Network error");
    }
  }, 1000);
});

fetchUserData
  .then((user) =&gt; {
    console.log("User:", user);
    console.log("Name:", user.name);
  })
  .catch((error) =&gt; {
    console.log("Failed to fetch:", error);
  });
</code></pre>
<h3>The .finally() Method</h3>
<p><code>.finally()</code> runs regardless of success or failure:</p>
<pre><code class="language-javascript">promise
  .then((value) =&gt; {
    console.log("Success:", value);
  })
  .catch((error) =&gt; {
    console.log("Error:", error);
  })
  .finally(() =&gt; {
    console.log("Operation complete (success or failure)");
  });
</code></pre>
<p>Use <code>.finally()</code> for cleanup code. Like closing a database connection.</p>
<hr />
<h2>Promise Chaining</h2>
<p>Promises can be chained. Each <code>.then()</code> returns a new promise.</p>
<h3>Why Chaining?</h3>
<p>Instead of nested callbacks:</p>
<pre><code class="language-javascript">// Callback hell
getUser(1, function(user) {
  getPostsForUser(user.id, function(posts) {
    console.log(posts);
  });
});
</code></pre>
<p>You can chain promises:</p>
<pre><code class="language-javascript">// Much cleaner
getUser(1)
  .then((user) =&gt; {
    return getPostsForUser(user.id);
  })
  .then((posts) =&gt; {
    console.log(posts);
  });
</code></pre>
<p>Linear. Readable. Each step is clear.</p>
<h3>How Chaining Works</h3>
<p>Each <code>.then()</code> returns a promise:</p>
<pre><code class="language-javascript">const step1 = getUser(1);          // Returns promise

const step2 = step1.then((user) =&gt; {
  return getPostsForUser(user.id);  // Returns new promise
});

const step3 = step2.then((posts) =&gt; {
  console.log(posts);               // No return = promise resolves with undefined
});
</code></pre>
<p>Or chained together:</p>
<pre><code class="language-javascript">getUser(1)
  .then((user) =&gt; {
    return getPostsForUser(user.id);
  })
  .then((posts) =&gt; {
    return getCommentsForPost(posts[0].id);
  })
  .then((comments) =&gt; {
    console.log(comments);
  })
  .catch((error) =&gt; {
    console.log("Something failed:", error);
  });
</code></pre>
<h3>Passing Data Through Chains</h3>
<pre><code class="language-javascript">getUser(1)
  .then((user) =&gt; {
    console.log("Step 1:", user);
    return getPostsForUser(user.id);  // Pass to next step
  })
  .then((posts) =&gt; {
    console.log("Step 2:", posts);
    return posts[0];                  // Pass post to next step
  })
  .then((firstPost) =&gt; {
    console.log("Step 3:", firstPost);
  });
</code></pre>
<p>Each step receives the return value from the previous step.</p>
<h3>Error Handling in Chains</h3>
<p>If any step fails, the chain stops and jumps to <code>.catch()</code>:</p>
<pre><code class="language-javascript">getUser(1)
  .then((user) =&gt; {
    return getPostsForUser(user.id);  // If this fails...
  })
  .then((posts) =&gt; {
    return getCommentsForPost(posts[0].id);  // This won't run
  })
  .then((comments) =&gt; {
    console.log(comments);             // This won't run
  })
  .catch((error) =&gt; {
    console.log("Error caught here:", error);  // Error caught here
  });
</code></pre>
<p>One error anywhere in the chain is caught at the end.</p>
<h3>Practical Example: Login Flow</h3>
<pre><code class="language-javascript">authenticateUser(email, password)
  .then((token) =&gt; {
    console.log("Login successful");
    return fetchUserData(token);  // Use token to fetch data
  })
  .then((user) =&gt; {
    console.log("User loaded:", user.name);
    return updateLastLogin(user.id);
  })
  .then(() =&gt; {
    console.log("Last login updated");
    redirectToDashboard();
  })
  .catch((error) =&gt; {
    console.log("Login failed:", error);
    showErrorMessage(error);
  });
</code></pre>
<p>Clean flow: authenticate → fetch → update → redirect.</p>
<hr />
<h2>Callback vs Promise Comparison</h2>
<h3>Callback Approach</h3>
<pre><code class="language-javascript">// Nested callbacks - "callback hell"
getUser(1, function(err, user) {
  if (err) {
    console.log("Error:", err);
  } else {
    getPostsForUser(user.id, function(err, posts) {
      if (err) {
        console.log("Error:", err);
      } else {
        getCommentsForPost(posts[0].id, function(err, comments) {
          if (err) {
            console.log("Error:", err);
          } else {
            console.log("Comments:", comments);
          }
        });
      }
    });
  }
});
</code></pre>
<p>Problems:</p>
<ul>
<li>Hard to read (pyramid of doom)</li>
<li>Error handling scattered everywhere</li>
<li>Difficult to follow the flow</li>
<li>Easy to make mistakes</li>
</ul>
<h3>Promise Approach</h3>
<pre><code class="language-javascript">// Clear chain - easy to follow
getUser(1)
  .then((user) =&gt; {
    return getPostsForUser(user.id);
  })
  .then((posts) =&gt; {
    return getCommentsForPost(posts[0].id);
  })
  .then((comments) =&gt; {
    console.log("Comments:", comments);
  })
  .catch((error) =&gt; {
    console.log("Error:", error);
  });
</code></pre>
<p>Benefits:</p>
<ul>
<li>Linear flow (top to bottom)</li>
<li>Error handling in one place</li>
<li>Easy to read</li>
<li>Easy to modify</li>
</ul>
<h3>Async/Await (Built on Promises)</h3>
<p>Modern JavaScript makes it even simpler:</p>
<pre><code class="language-javascript">// Built on top of promises - looks like synchronous code
async function loadComments() {
  try {
    const user = await getUser(1);
    const posts = await getPostsForUser(user.id);
    const comments = await getCommentsForPost(posts[0].id);
    console.log("Comments:", comments);
  } catch (error) {
    console.log("Error:", error);
  }
}

loadComments();
</code></pre>
<p>Same promise behavior, but the syntax is simpler.</p>
<hr />
<h2>Common Promise Patterns</h2>
<h3>Promise.all() - Wait for All</h3>
<p>Run multiple operations in parallel and wait for all:</p>
<pre><code class="language-javascript">const user = getUser(1);
const posts = getPostsForUser(1);
const comments = getComments(1);

Promise.all([user, posts, comments])
  .then(([userData, postsData, commentsData]) =&gt; {
    console.log("All data loaded");
    console.log("User:", userData);
    console.log("Posts:", postsData);
    console.log("Comments:", commentsData);
  })
  .catch((error) =&gt; {
    console.log("One or more failed:", error);
  });
</code></pre>
<p>If any promise fails, the whole thing fails.</p>
<h3>Promise.race() - Wait for First</h3>
<p>Run multiple operations and use the result of whichever finishes first:</p>
<pre><code class="language-javascript">const timeout = new Promise((resolve, reject) =&gt; {
  setTimeout(() =&gt; reject("Timeout"), 5000);
});

const apiCall = fetchData();

Promise.race([apiCall, timeout])
  .then((result) =&gt; {
    console.log("Got result:", result);
  })
  .catch((error) =&gt; {
    console.log("Failed or timed out:", error);
  });
</code></pre>
<p>Useful for timeout handling.</p>
<h3>Promise.resolve() - Instant Success</h3>
<p>Create a promise that's already fulfilled:</p>
<pre><code class="language-javascript">const instantPromise = Promise.resolve("Done!");

instantPromise.then((value) =&gt; {
  console.log(value);  // "Done!" (runs immediately)
});
</code></pre>
<h3>Promise.reject() - Instant Failure</h3>
<p>Create a promise that's already rejected:</p>
<pre><code class="language-javascript">const failedPromise = Promise.reject("Error!");

failedPromise.catch((error) =&gt; {
  console.log(error);  // "Error!" (runs immediately)
});
</code></pre>
<hr />
<h2>Complete Example: Building a Promise</h2>
<pre><code class="language-javascript">// Create a promise that simulates an API call
function fetchUserData(userId) {
  return new Promise((resolve, reject) =&gt; {
    // Simulate network delay
    setTimeout(() =&gt; {
      // Simulate success/failure
      if (userId &gt; 0) {
        const user = { id: userId, name: "Alice", email: "alice@example.com" };
        resolve(user);  // Success
      } else {
        reject("Invalid user ID");  // Failure
      }
    }, 1000);
  });
}

// Use the promise
fetchUserData(1)
  .then((user) =&gt; {
    console.log("Fetched user:", user.name);
    return fetchUserPosts(user.id);
  })
  .then((posts) =&gt; {
    console.log("User has", posts.length, "posts");
  })
  .catch((error) =&gt; {
    console.log("Failed:", error);
  })
  .finally(() =&gt; {
    console.log("Operation complete");
  });

// Test with invalid ID
fetchUserData(-1)
  .then((user) =&gt; {
    console.log("User:", user);
  })
  .catch((error) =&gt; {
    console.log("Error:", error);
  });
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Create a simple promise:</strong></p>
<pre><code class="language-javascript">// Create a promise that resolves with "Hello"
// After 1 second
// Use .then() to log the result
</code></pre>
<p><strong>2. Handle both success and failure:</strong></p>
<pre><code class="language-javascript">// Create a promise that randomly resolves or rejects
// Implement .then() and .catch()
// Test multiple times
</code></pre>
<p><strong>3. Chain multiple promises:</strong></p>
<pre><code class="language-javascript">// Create three functions that return promises
// Each one should use the result of the previous
// Chain them together with .then()
// Add error handling with .catch()
</code></pre>
<p><strong>4. Compare callbacks vs promises:</strong></p>
<pre><code class="language-javascript">// Write the same operation with callbacks
// Then rewrite with promises
// Notice the difference in readability
</code></pre>
<p><strong>5. Use Promise.all():</strong></p>
<pre><code class="language-javascript">// Create three promises that fetch different data
// Use Promise.all() to wait for all of them
// Handle success and failure
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Promises</strong> represent values that don't exist yet but will exist in the future.</p>
</li>
<li><p>A promise solves the <strong>callback hell</strong> problem by making asynchronous code readable.</p>
</li>
<li><p>Promises are like a receipt at a restaurant: you don't have the cake yet, but the receipt promises you'll get it.</p>
</li>
<li><p><strong>Pending</strong> state: promise is waiting for an operation to complete.</p>
</li>
<li><p><strong>Fulfilled</strong> state: operation succeeded and the promise has a value.</p>
</li>
<li><p><strong>Rejected</strong> state: operation failed and the promise has an error.</p>
</li>
<li><p>A promise transitions from pending to either fulfilled or rejected, never both.</p>
</li>
<li><p>Once a promise is fulfilled or rejected, it cannot change states again.</p>
</li>
<li><p><strong>resolve(value)</strong> moves a promise to fulfilled state with a value.</p>
</li>
<li><p><strong>reject(error)</strong> moves a promise to rejected state with an error.</p>
</li>
<li><p><strong>.then(callback)</strong> handles successful completion (fulfilled state).</p>
</li>
<li><p><strong>.catch(callback)</strong> handles failure (rejected state).</p>
</li>
<li><p><strong>.finally(callback)</strong> runs regardless of success or failure.</p>
</li>
<li><p><strong>Promise chaining</strong> allows multiple operations in sequence with <code>.then().then().then()</code>.</p>
</li>
<li><p>Each <code>.then()</code> returns a new promise, enabling chaining.</p>
</li>
<li><p>Errors in a promise chain jump to the nearest <code>.catch()</code>.</p>
</li>
<li><p><strong>Promise.all()</strong> waits for multiple promises, failing if any fails.</p>
</li>
<li><p><strong>Promise.race()</strong> waits for the first promise to complete.</p>
</li>
<li><p><strong>Callbacks</strong> are harder to read and lead to "callback hell."</p>
</li>
<li><p><strong>Promises</strong> are cleaner and more maintainable.</p>
</li>
<li><p><strong>Async/await</strong> is built on top of promises and makes code even simpler.</p>
</li>
</ul>
<p>Promises are the foundation of modern JavaScript asynchronous programming.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Handling File Uploads in Express with Multer
]]></title><description><![CDATA[File uploads are tricky. The browser sends files in a special format, your server needs to parse them, and you need to store them safely. Multer handles all of this automatically with just a few lines]]></description><link>https://blog.harshx.in/handling-file-uploads-in-express-with-multer</link><guid isPermaLink="true">https://blog.harshx.in/handling-file-uploads-in-express-with-multer</guid><category><![CDATA[Node.js]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 11:18:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/78474efb-61c3-48e2-b4f3-918492f24273.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p> File uploads are tricky. The browser sends files in a special format, your server needs to parse them, and you need to store them safely. Multer handles all of this automatically with just a few lines of code.</p>
<p>This is about understanding how file uploads work and building upload systems with Express and Multer.</p>
<hr />
<h2>Why File Uploads Need Middleware</h2>
<p>When a user uploads a file, the browser doesn't send it like normal form data.</p>
<h3>Regular Form Data</h3>
<pre><code class="language-javascript">// Normal form data
const data = {
  name: "Alice",
  email: "alice@example.com"
};

// Sent as URL-encoded
name=Alice&amp;email=alice@example.com
</code></pre>
<p>Express can parse this automatically with <code>express.urlencoded()</code>.</p>
<h3>File Uploads Are Different</h3>
<p>Files are binary data. They can't be sent as simple text like <code>name=Alice&amp;email=alice@example.com</code>.</p>
<p>The browser uses a special format called <strong>multipart/form-data</strong>.</p>
<h3>What is Multipart/Form-Data?</h3>
<p>Think of it like a package with multiple items:</p>
<pre><code class="language-plaintext">------boundary123456
Content-Disposition: form-data; name="email"

alice@example.com
------boundary123456
Content-Disposition: form-data; name="file"; filename="resume.pdf"
Content-Type: application/pdf

[binary file data here]
------boundary123456--
</code></pre>
<p>It's a special format that separates form fields and files with boundaries.</p>
<h3>Why You Need Middleware</h3>
<p>Express by itself cannot:</p>
<ul>
<li>Parse multipart/form-data</li>
<li>Extract files from the request</li>
<li>Save files to disk</li>
<li>Handle file streams safely</li>
</ul>
<p>Without middleware, you'd have to:</p>
<pre><code class="language-javascript">// Without middleware: painful
app.post("/upload", (req, res) =&gt; {
  // Manually parse multipart boundaries
  // Manually extract binary data
  // Manually save to disk
  // Manually handle errors
  // 100+ lines of code
});
</code></pre>
<p>With Multer:</p>
<pre><code class="language-javascript">// With Multer: simple
app.post("/upload", multer({ dest: "uploads/" }).single("file"), (req, res) =&gt; {
  // File is already saved
  res.json({ message: "File uploaded" });
});
</code></pre>
<p>That's why you need middleware for file uploads.</p>
<hr />
<h2>What is Multer?</h2>
<p>Multer is Express middleware that handles multipart/form-data.</p>
<h3>Simple Definition</h3>
<p>Multer is a library that:</p>
<ul>
<li>Parses incoming file uploads</li>
<li>Extracts files from requests</li>
<li>Saves files to your server</li>
<li>Provides file information to your route</li>
</ul>
<p>It sits between the client and your route handler.</p>
<h3>Real Example</h3>
<pre><code class="language-plaintext">Client sends file
      |
      v
Multer receives multipart/form-data
      |
      v
Multer parses the boundaries
      |
      v
Multer extracts the file
      |
      v
Multer saves to disk (or memory)
      |
      v
Your route handler gets req.file
      |
      v
You send response
</code></pre>
<h3>Why Multer</h3>
<p>Before Multer, developers had to:</p>
<ul>
<li>Manually parse multipart boundaries</li>
<li>Handle file streams</li>
<li>Validate file types</li>
<li>Manage storage locations</li>
</ul>
<p>Multer automates all of this.</p>
<h3>Installation</h3>
<pre><code class="language-bash">npm install multer
</code></pre>
<hr />
<h2>Multer Middleware Execution Flow</h2>
<pre><code class="language-plaintext">Request arrives with file
      |
      v
Multer checks Content-Type
(must be multipart/form-data)
      |
      v
Multer parses boundaries
      |
      v
Multer extracts file(s)
      |
      v
Multer validates (size, type, etc)
      |
      v
Multer saves to destination
      |
      v
Multer populates req.file or req.files
      |
      v
Route handler executes
</code></pre>
<p>The middleware does all the heavy lifting before your code runs.</p>
<hr />
<h2>Handling Single File Upload</h2>
<h3>Basic Setup</h3>
<pre><code class="language-javascript">const express = require("express");
const multer = require("multer");

const app = express();

// Configure multer
const upload = multer({ dest: "uploads/" });

// Single file upload route
app.post("/upload", upload.single("file"), (req, res) =&gt; {
  // req.file contains the uploaded file
  res.json({
    message: "File uploaded successfully",
    file: req.file
  });
});

app.listen(3000, () =&gt; {
  console.log("Server running on http://localhost:3000");
});
</code></pre>
<h3>What Happens</h3>
<ol>
<li>Client sends file in form field named "file"</li>
<li>Multer intercepts the request</li>
<li>Multer saves file to <code>uploads/</code> directory</li>
<li>Multer adds <code>req.file</code> object to the request</li>
<li>Route handler accesses <code>req.file</code></li>
</ol>
<h3>The req.file Object</h3>
<pre><code class="language-javascript">app.post("/upload", upload.single("file"), (req, res) =&gt; {
  console.log(req.file);
  // Outputs:
  // {
  //   fieldname: "file",          // Form field name
  //   originalname: "resume.pdf",  // Original filename
  //   encoding: "7bit",            // File encoding
  //   mimetype: "application/pdf",  // File type
  //   destination: "uploads/",     // Where it was saved
  //   filename: "abc123def456",    // Saved filename (random)
  //   path: "uploads/abc123def456", // Full path
  //   size: 45678                  // File size in bytes
  // }
  
  res.json({
    filename: req.file.filename,
    size: req.file.size,
    mimetype: req.file.mimetype
  });
});
</code></pre>
<h3>HTML Form for Upload</h3>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;body&gt;
  &lt;form action="http://localhost:3000/upload" method="POST" enctype="multipart/form-data"&gt;
    &lt;input type="file" name="file" required&gt;
    &lt;button type="submit"&gt;Upload&lt;/button&gt;
  &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>Important: The <code>enctype="multipart/form-data"</code> is required. Without it, the file isn't sent correctly.</p>
<h3>Test With curl</h3>
<pre><code class="language-bash">curl -X POST \
  -F "file=@resume.pdf" \
  http://localhost:3000/upload
</code></pre>
<p>The <code>-F</code> flag tells curl to send as multipart/form-data.</p>
<hr />
<h2>Handling Multiple File Uploads</h2>
<h3>Multiple Files, Single Field</h3>
<p>Upload several files using the same form field:</p>
<pre><code class="language-javascript">const express = require("express");
const multer = require("multer");

const app = express();
const upload = multer({ dest: "uploads/" });

app.post("/upload-multiple", upload.array("files", 10), (req, res) =&gt; {
  // req.files is an array of file objects
  res.json({
    message: "Files uploaded",
    count: req.files.length,
    files: req.files.map(f =&gt; ({
      filename: f.filename,
      size: f.size
    }))
  });
});

app.listen(3000);
</code></pre>
<h3>What Changed</h3>
<p><code>.single("file")</code> becomes <code>.array("files", 10)</code>.</p>
<p>The second argument is the maximum number of files allowed. This prevents abuse.</p>
<h3>req.files Array</h3>
<pre><code class="language-javascript">app.post("/upload-multiple", upload.array("files", 10), (req, res) =&gt; {
  console.log(req.files);
  // Outputs array of file objects:
  // [
  //   { fieldname: "files", originalname: "doc1.pdf", ... },
  //   { fieldname: "files", originalname: "doc2.pdf", ... },
  //   { fieldname: "files", originalname: "doc3.pdf", ... }
  // ]
  
  req.files.forEach(file =&gt; {
    console.log(`\({file.originalname} (\){file.size} bytes)`);
  });
});
</code></pre>
<h3>HTML Form for Multiple Files</h3>
<pre><code class="language-html">&lt;form action="http://localhost:3000/upload-multiple" method="POST" enctype="multipart/form-data"&gt;
  &lt;input type="file" name="files" multiple required&gt;
  &lt;button type="submit"&gt;Upload Files&lt;/button&gt;
&lt;/form&gt;
</code></pre>
<p>The <code>multiple</code> attribute lets users select multiple files.</p>
<h3>Different Fields, Different Files</h3>
<p>Upload files to different form fields:</p>
<pre><code class="language-javascript">// .fields() takes an array of field configurations
const upload = multer({ dest: "uploads/" });

app.post("/upload-mixed", upload.fields([
  { name: "avatar", maxCount: 1 },
  { name: "documents", maxCount: 5 }
]), (req, res) =&gt; {
  console.log(req.files);
  // Outputs:
  // {
  //   avatar: [ { file object } ],
  //   documents: [ { file object }, { file object }, ... ]
  // }
  
  const avatar = req.files.avatar[0];
  const docs = req.files.documents;
  
  res.json({ avatar, docs });
});
</code></pre>
<h3>HTML Form with Multiple Fields</h3>
<pre><code class="language-html">&lt;form action="http://localhost:3000/upload-mixed" method="POST" enctype="multipart/form-data"&gt;
  &lt;label&gt;Profile Picture&lt;/label&gt;
  &lt;input type="file" name="avatar" required&gt;
  
  &lt;label&gt;Documents&lt;/label&gt;
  &lt;input type="file" name="documents" multiple required&gt;
  
  &lt;button type="submit"&gt;Upload&lt;/button&gt;
&lt;/form&gt;
</code></pre>
<hr />
<h2>Storage Configuration Basics</h2>
<p>By default, Multer saves files with random names. You might want to customize this.</p>
<h3>Memory Storage</h3>
<p>Store files in RAM instead of disk:</p>
<pre><code class="language-javascript">const multer = require("multer");

// Memory storage (files in RAM)
const storage = multer.memoryStorage();
const upload = multer({ storage });

app.post("/upload", upload.single("file"), (req, res) =&gt; {
  // File is in memory
  console.log(req.file);
  // {
  //   fieldname: "file",
  //   originalname: "resume.pdf",
  //   encoding: "7bit",
  //   mimetype: "application/pdf",
  //   buffer: &lt;Buffer...&gt;,    // File binary data
  //   size: 45678
  // }
  
  // No destination or path (it's in RAM)
  res.json({ message: "File received" });
});
</code></pre>
<p>Use memory storage when:</p>
<ul>
<li>Files are small</li>
<li>You process them immediately</li>
<li>You don't need to persist them</li>
</ul>
<p>Don't use memory storage when:</p>
<ul>
<li>Files are large (drains RAM)</li>
<li>Many users upload simultaneously</li>
<li>You need to store files permanently</li>
</ul>
<h3>Disk Storage with Custom Names</h3>
<p>Save to disk with meaningful filenames:</p>
<pre><code class="language-javascript">const multer = require("multer");
const path = require("path");

// Disk storage with custom configuration
const storage = multer.diskStorage({
  destination: (req, file, cb) =&gt; {
    // Where to save
    cb(null, "uploads/");
  },
  filename: (req, file, cb) =&gt; {
    // How to name the file
    // cb(null, originalname) keeps the original name
    // But this is risky (filename injection)
    
    // Better: use timestamp + original extension
    const uniqueName = Date.now() + path.extname(file.originalname);
    cb(null, uniqueName);
  }
});

const upload = multer({ storage });

app.post("/upload", upload.single("file"), (req, res) =&gt; {
  console.log(req.file.filename);
  // Output: 1620000000000.pdf
  
  res.json({ filename: req.file.filename });
});
</code></pre>
<h3>Safe Filename Strategy</h3>
<p>Never trust the user's filename. Always generate your own:</p>
<pre><code class="language-javascript">const storage = multer.diskStorage({
  destination: (req, file, cb) =&gt; {
    cb(null, "uploads/");
  },
  filename: (req, file, cb) =&gt; {
    // Option 1: Timestamp + extension
    const filename = Date.now() + path.extname(file.originalname);
    cb(null, filename);
    
    // Option 2: UUID + extension
    // const filename = uuid() + path.extname(file.originalname);
    // cb(null, filename);
    
    // Option 3: User ID + timestamp
    // const filename = req.user.id + "-" + Date.now() + path.extname(file.originalname);
    // cb(null, filename);
  }
});
</code></pre>
<p>Always append the file extension to preserve file type.</p>
<h3>Complete Storage Example</h3>
<pre><code class="language-javascript">const express = require("express");
const multer = require("multer");
const path = require("path");

const app = express();

// Configure storage
const storage = multer.diskStorage({
  destination: (req, file, cb) =&gt; {
    cb(null, "uploads/");
  },
  filename: (req, file, cb) =&gt; {
    const uniqueName = Date.now() + path.extname(file.originalname);
    cb(null, uniqueName);
  }
});

const upload = multer({
  storage,
  limits: { fileSize: 5 * 1024 * 1024 }, // 5MB max
  fileFilter: (req, file, cb) =&gt; {
    // Only allow PDF and images
    const allowedMimes = ["application/pdf", "image/jpeg", "image/png"];
    if (allowedMimes.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new Error("Invalid file type"));
    }
  }
});

app.post("/upload", upload.single("file"), (req, res) =&gt; {
  res.json({
    message: "File uploaded",
    filename: req.file.filename,
    size: req.file.size
  });
});

app.listen(3000);
</code></pre>
<p>Key options:</p>
<ul>
<li><code>limits.fileSize</code>: Maximum file size in bytes</li>
<li><code>fileFilter</code>: Validate file type, name, or size</li>
</ul>
<hr />
<h2>Serving Uploaded Files</h2>
<p>After uploading, users need to download or view files.</p>
<h3>Static File Serving</h3>
<p>Tell Express to serve files from the uploads directory:</p>
<pre><code class="language-javascript">const express = require("express");
const multer = require("multer");

const app = express();

// Serve uploaded files as static
app.use("/uploads", express.static("uploads/"));

const storage = multer.diskStorage({
  destination: (req, file, cb) =&gt; {
    cb(null, "uploads/");
  },
  filename: (req, file, cb) =&gt; {
    cb(null, Date.now() + path.extname(file.originalname));
  }
});

const upload = multer({ storage });

app.post("/upload", upload.single("file"), (req, res) =&gt; {
  const fileUrl = `/uploads/${req.file.filename}`;
  
  res.json({
    message: "File uploaded",
    url: fileUrl  // Client can access at this URL
  });
});

app.listen(3000);
</code></pre>
<p>Now files are accessible at <code>http://localhost:3000/uploads/filename</code>.</p>
<h3>Downloading vs Viewing</h3>
<p>In the browser, images display. But PDFs should download:</p>
<pre><code class="language-javascript">app.get("/download/:filename", (req, res) =&gt; {
  const filename = req.params.filename;
  const filepath = path.join(__dirname, "uploads", filename);
  
  // Force download
  res.download(filepath);
});
</code></pre>
<p>The <code>.download()</code> method tells the browser to download instead of display.</p>
<h3>Complete Upload and Download Example</h3>
<pre><code class="language-javascript">const express = require("express");
const multer = require("multer");
const path = require("path");

const app = express();

// Serve uploads folder
app.use("/uploads", express.static("uploads/"));

const storage = multer.diskStorage({
  destination: (req, file, cb) =&gt; {
    cb(null, "uploads/");
  },
  filename: (req, file, cb) =&gt; {
    cb(null, Date.now() + path.extname(file.originalname));
  }
});

const upload = multer({ storage });

// Upload endpoint
app.post("/upload", upload.single("file"), (req, res) =&gt; {
  res.json({
    message: "File uploaded",
    filename: req.file.filename,
    url: `/uploads/${req.file.filename}`
  });
});

// Download endpoint
app.get("/download/:filename", (req, res) =&gt; {
  const filepath = path.join(__dirname, "uploads", req.params.filename);
  res.download(filepath);
});

// View files endpoint
app.get("/files", (req, res) =&gt; {
  const fs = require("fs");
  const files = fs.readdirSync("uploads/");
  
  res.json({ files });
});

app.listen(3000, () =&gt; {
  console.log("Server running on http://localhost:3000");
});
</code></pre>
<h3>Test Upload and Download</h3>
<p>Upload:</p>
<pre><code class="language-bash">curl -X POST \
  -F "file=@resume.pdf" \
  http://localhost:3000/upload
</code></pre>
<p>Response:</p>
<pre><code class="language-json">{
  "message": "File uploaded",
  "filename": "1620000000000.pdf",
  "url": "/uploads/1620000000000.pdf"
}
</code></pre>
<p>Download:</p>
<pre><code class="language-bash">curl -O http://localhost:3000/download/1620000000000.pdf
</code></pre>
<p>Or in the browser: <code>http://localhost:3000/uploads/1620000000000.pdf</code></p>
<hr />
<h2>Client to Server to Storage Upload Lifecycle</h2>
<pre><code class="language-plaintext">User selects file in browser
      |
      v
Form sends POST request
(multipart/form-data format)
      |
      v
Express receives request
      |
      v
Multer middleware intercepts
      |
      v
Multer parses multipart boundaries
      |
      v
Multer extracts file data
      |
      v
Multer validates file
(type, size, filters)
      |
      ├─ Invalid → Error response
      └─ Valid → Continue
      |
      v
Multer saves to disk
(or memory)
      |
      v
Multer populates req.file
      |
      v
Route handler executes
      |
      v
Handler sends response
(with file info/URL)
      |
      v
Browser receives response
      |
      v
User can access file at URL
</code></pre>
<hr />
<h2>Common Multer Options</h2>
<h3>File Size Limits</h3>
<pre><code class="language-javascript">const upload = multer({
  storage,
  limits: {
    fileSize: 5 * 1024 * 1024  // 5MB
  }
});
</code></pre>
<p>Reject files larger than 5MB.</p>
<h3>File Type Validation</h3>
<pre><code class="language-javascript">const upload = multer({
  storage,
  fileFilter: (req, file, cb) =&gt; {
    if (file.mimetype === "application/pdf") {
      cb(null, true);  // Accept
    } else {
      cb(new Error("Only PDF files allowed"));  // Reject
    }
  }
});
</code></pre>
<p>Only allow PDFs. Reject other types.</p>
<h3>Multiple Extensions</h3>
<pre><code class="language-javascript">const upload = multer({
  storage,
  fileFilter: (req, file, cb) =&gt; {
    const allowedTypes = ["image/jpeg", "image/png", "application/pdf"];
    
    if (allowedTypes.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new Error("Invalid file type"));
    }
  }
});
</code></pre>
<p>Allow images and PDFs.</p>
<h3>Error Handling</h3>
<pre><code class="language-javascript">app.post("/upload", (req, res) =&gt; {
  upload.single("file")(req, res, (err) =&gt; {
    if (err instanceof multer.MulterError) {
      // Multer error (file too large, etc)
      return res.status(400).json({ error: err.message });
    } else if (err) {
      // Custom error (from fileFilter)
      return res.status(400).json({ error: err.message });
    }
    
    // Success
    res.json({ message: "File uploaded", file: req.file });
  });
});
</code></pre>
<p>Catch both Multer errors and custom validation errors.</p>
<hr />
<h2>Complete Practical Example</h2>
<pre><code class="language-javascript">const express = require("express");
const multer = require("multer");
const path = require("path");
const fs = require("fs");

const app = express();
app.use(express.json());

// Create uploads folder if it doesn't exist
if (!fs.existsSync("uploads/")) {
  fs.mkdirSync("uploads/");
}

// Serve uploaded files
app.use("/uploads", express.static("uploads/"));

// Configure storage
const storage = multer.diskStorage({
  destination: (req, file, cb) =&gt; {
    cb(null, "uploads/");
  },
  filename: (req, file, cb) =&gt; {
    const uniqueName = Date.now() + path.extname(file.originalname);
    cb(null, uniqueName);
  }
});

// Configure upload with validation
const upload = multer({
  storage,
  limits: { fileSize: 5 * 1024 * 1024 }, // 5MB max
  fileFilter: (req, file, cb) =&gt; {
    const allowedTypes = ["image/jpeg", "image/png", "application/pdf"];
    if (allowedTypes.includes(file.mimetype)) {
      cb(null, true);
    } else {
      cb(new Error("Only JPEG, PNG, and PDF files are allowed"));
    }
  }
});

// Single file upload
app.post("/upload", (req, res) =&gt; {
  upload.single("file")(req, res, (err) =&gt; {
    if (err) {
      return res.status(400).json({ error: err.message });
    }
    
    if (!req.file) {
      return res.status(400).json({ error: "No file provided" });
    }
    
    res.json({
      message: "File uploaded successfully",
      file: {
        filename: req.file.filename,
        originalname: req.file.originalname,
        size: req.file.size,
        url: `/uploads/${req.file.filename}`
      }
    });
  });
});

// Multiple files upload
app.post("/upload-multiple", (req, res) =&gt; {
  upload.array("files", 10)(req, res, (err) =&gt; {
    if (err) {
      return res.status(400).json({ error: err.message });
    }
    
    if (!req.files || req.files.length === 0) {
      return res.status(400).json({ error: "No files provided" });
    }
    
    const files = req.files.map(f =&gt; ({
      filename: f.filename,
      originalname: f.originalname,
      size: f.size,
      url: `/uploads/${f.filename}`
    }));
    
    res.json({
      message: "Files uploaded successfully",
      count: files.length,
      files
    });
  });
});

// List uploaded files
app.get("/files", (req, res) =&gt; {
  fs.readdir("uploads/", (err, files) =&gt; {
    if (err) {
      return res.status(500).json({ error: "Could not read files" });
    }
    
    res.json({ files });
  });
});

// Download file
app.get("/download/:filename", (req, res) =&gt; {
  const filepath = path.join(__dirname, "uploads", req.params.filename);
  
  // Prevent directory traversal attacks
  if (!filepath.startsWith(path.join(__dirname, "uploads"))) {
    return res.status(403).json({ error: "Forbidden" });
  }
  
  res.download(filepath);
});

app.listen(3000, () =&gt; {
  console.log("Server running on http://localhost:3000");
});
</code></pre>
<p>Test it:</p>
<pre><code class="language-bash"># Upload single file
curl -X POST \
  -F "file=@resume.pdf" \
  http://localhost:3000/upload

# Upload multiple files
curl -X POST \
  -F "files=@file1.pdf" \
  -F "files=@file2.pdf" \
  http://localhost:3000/upload-multiple

# List files
curl http://localhost:3000/files

# Download file
curl -O http://localhost:3000/download/1620000000000.pdf
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Build a single file upload route:</strong></p>
<pre><code class="language-javascript">// Create POST /upload endpoint
// Accept file in "file" form field
// Save to "uploads/" directory
// Return uploaded file info
// Test with curl
</code></pre>
<p><strong>2. Add file validation:</strong></p>
<pre><code class="language-javascript">// Validate file type (only PDF and images)
// Validate file size (max 2MB)
// Return error if validation fails
// Test with invalid file
</code></pre>
<p><strong>3. Create multiple file upload:</strong></p>
<pre><code class="language-javascript">// Create POST /upload-multiple endpoint
// Accept up to 5 files in "files" field
// Save all files
// Return array of file info
// Test with multiple files
</code></pre>
<p><strong>4. Serve uploaded files:</strong></p>
<pre><code class="language-javascript">// Use express.static() for uploads folder
// Create GET /files endpoint to list all files
// Create GET /download/:filename endpoint
// Test accessing and downloading files
</code></pre>
<p><strong>5. Add error handling:</strong></p>
<pre><code class="language-javascript">// Handle Multer errors (file too large)
// Handle custom validation errors
// Return meaningful error messages
// Test with various error scenarios
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>File uploads</strong> are sent as multipart/form-data, a special format the browser uses to send binary data.</p>
</li>
<li><p><strong>Middleware</strong> is needed because Express doesn't parse multipart/form-data by default.</p>
</li>
<li><p><strong>Multer</strong> is Express middleware that parses multipart/form-data and saves files.</p>
</li>
<li><p><code>.single("field")</code> uploads one file from form field "field".</p>
</li>
<li><p><code>.array("field", max)</code> uploads multiple files from the same field.</p>
</li>
<li><p><code>.fields()</code> uploads different files to different fields.</p>
</li>
<li><p><strong>req.file</strong> contains info about a single uploaded file (with <code>.single()</code>).</p>
</li>
<li><p><strong>req.files</strong> contains info about multiple uploaded files (with <code>.array()</code> or <code>.fields()</code>).</p>
</li>
<li><p><strong>Memory storage</strong> stores files in RAM (good for small, temporary files).</p>
</li>
<li><p><strong>Disk storage</strong> saves files to the server filesystem (good for persistent storage).</p>
</li>
<li><p>Always use custom filenames to prevent <strong>filename injection attacks</strong>.</p>
</li>
<li><p><strong>File validation</strong> with <code>fileFilter</code> prevents unwanted file types.</p>
</li>
<li><p><strong>File size limits</strong> prevent storage abuse.</p>
</li>
<li><p><code>express.static()</code> serves uploaded files so users can access them.</p>
</li>
<li><p><code>res.download()</code> forces download instead of viewing in the browser.</p>
</li>
<li><p>Multipart/form-data requires the HTML form attribute <code>enctype="multipart/form-data"</code>.</p>
</li>
</ul>
<p>Multer makes file uploads simple and secure.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[What is Node.js? JavaScript on the Server Explained
]]></title><description><![CDATA[Node.js lets you run JavaScript outside the browser—on servers, databases, and beyond. Instead of learning a new language for the backend, you write the same JavaScript everywhere.
This is about under]]></description><link>https://blog.harshx.in/what-is-node-js</link><guid isPermaLink="true">https://blog.harshx.in/what-is-node-js</guid><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 11:14:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/f5397931-261d-4dba-9b31-31f760a8c993.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p> Node.js lets you run JavaScript outside the browser—on servers, databases, and beyond. Instead of learning a new language for the backend, you write the same JavaScript everywhere.</p>
<p>This is about understanding what Node.js is and why it changed how we build web applications.</p>
<hr />
<h2>What is Node.js?</h2>
<p>Node.js is a runtime environment that executes JavaScript code outside the browser.</p>
<h3>The Simple Definition</h3>
<p><strong>Runtime</strong> = An environment where code runs.
<strong>JavaScript runtime</strong> = A place where JavaScript code executes.</p>
<p>Before Node.js, only browsers could run JavaScript. Node.js made it possible to run JavaScript on servers too.</p>
<h3>Real Example</h3>
<p>Before Node.js:</p>
<pre><code>Frontend: JavaScript (in browser)
Backend: PHP, Python, Java (on server)
You had to learn multiple languages
</code></pre>
<p>After Node.js:</p>
<pre><code>Frontend: JavaScript (in browser)
Backend: JavaScript (on server)
One language everywhere
</code></pre>
<h3>Why This Matters</h3>
<p>Most developers already knew JavaScript for the browser. Node.js meant they could write backend code without learning a new language.</p>
<hr />
<h2>Why Was JavaScript Browser-Only?</h2>
<p>JavaScript was literally created for browsers.</p>
<h3>The Origin Story (1995)</h3>
<p>Brendan Eich created JavaScript in 10 days for Netscape Navigator. It was designed to:</p>
<ul>
<li>Run in web browsers</li>
<li>Manipulate HTML and CSS</li>
<li>Respond to user interactions</li>
<li>Validate forms</li>
</ul>
<p>There was no concept of "server-side JavaScript" in 1995.</p>
<h3>Browser Capabilities</h3>
<p>Browsers had everything JavaScript needed:</p>
<pre><code class="language-javascript">// Browser JavaScript
document.getElementById("button").addEventListener("click", () =&gt; {
  alert("Button clicked!");
});
</code></pre>
<p>The browser provided <code>document</code>, <code>window</code>, DOM APIs, etc. These only existed in browsers.</p>
<h3>No Server Features</h3>
<p>JavaScript had no way to:</p>
<ul>
<li>Read/write files on disk</li>
<li>Connect to databases</li>
<li>Listen for incoming network requests</li>
<li>Run as a long-lived process</li>
</ul>
<p>It was perfectly designed for browsers. Just not for servers.</p>
<hr />
<h2>How Node.js Changed Everything</h2>
<h3>The Breakthrough (2009)</h3>
<p>Ryan Dahl created Node.js with a radical idea: <strong>take the JavaScript engine from Chrome and let it run on servers.</strong></p>
<p>Instead of creating a new language or runtime, he reused existing JavaScript technology.</p>
<h3>What Node.js Added</h3>
<p>Node.js removed browser APIs and added server APIs:</p>
<pre><code class="language-javascript">// Browser (Node.js can't do this)
document.getElementById("button");  // No document
window.alert("Hi");                 // No window

// Server (Node.js can do this)
const fs = require("fs");           // Read files
const http = require("http");       // Create servers
const net = require("net");         // Network sockets
</code></pre>
<h3>The JavaScript Runtime Difference</h3>
<pre><code class="language-plaintext">Browser Runtime (JavaScript)
├─ JavaScript language (same)
├─ DOM API (document, element)
├─ Window API (localStorage, fetch)
├─ Event system (click, scroll)
└─ Security sandbox (can't access disk)

Node.js Runtime (JavaScript)
├─ JavaScript language (same)
├─ File System (fs module)
├─ HTTP Server (http module)
├─ OS utilities (os, path modules)
└─ Full disk/network access
</code></pre>
<p>Same language. Different APIs.</p>
<hr />
<h2>Browser JS vs Server JS: The Analogy</h2>
<h3>Browser JavaScript</h3>
<p>Think of browser JavaScript as a <strong>theater actor</strong>:</p>
<ul>
<li>Performs on stage (the browser window)</li>
<li>Interacts with the audience (user clicks, scrolls)</li>
<li>Props and scenery are provided (DOM, document)</li>
<li>Can't leave the theater</li>
<li>Limited to what the stage allows</li>
</ul>
<pre><code class="language-javascript">// Browser: responding to user
button.addEventListener("click", () =&gt; {
  console.log("User clicked");
});
</code></pre>
<h3>Server JavaScript (Node.js)</h3>
<p>Think of server JavaScript as a <strong>factory manager</strong>:</p>
<ul>
<li>Runs operations behind the scenes</li>
<li>Doesn't interact with users directly</li>
<li>Controls machinery (databases, files, networks)</li>
<li>Runs 24/7</li>
<li>Manages resources and processes</li>
</ul>
<pre><code class="language-javascript">// Server: listening for requests
server.listen(3000, () =&gt; {
  console.log("Server running");
});
</code></pre>
<p>Different roles. Same skill (JavaScript).</p>
<hr />
<h2>The V8 Engine: Under the Hood</h2>
<h3>What is V8?</h3>
<p>V8 is <strong>Google's JavaScript engine</strong>. It's what makes JavaScript fast.</p>
<h3>JavaScript vs Runtime</h3>
<pre><code class="language-plaintext">JavaScript (language)
  ↓
V8 Engine (converts to machine code)
  ↓
Computer (executes)
</code></pre>
<p>V8 takes JavaScript code and compiles it to machine code so computers can run it blazingly fast.</p>
<h3>Why V8 Matters</h3>
<p>Before V8 (early 2000s):</p>
<ul>
<li>JavaScript was interpreted line-by-line</li>
<li>Slow</li>
</ul>
<p>V8 (2008+):</p>
<ul>
<li>Compiles JavaScript to machine code</li>
<li>~1000x faster</li>
</ul>
<p>Node.js uses V8, which is why JavaScript on servers can be performant.</p>
<h3>You Don't Need to Know the Details</h3>
<p>For this article, just remember:</p>
<pre><code class="language-plaintext">Browser: runs V8 engine
Node.js: also runs V8 engine
Both execute the same JavaScript differently
</code></pre>
<p>The engine is the same. The environment is different.</p>
<hr />
<h2>Event-Driven Architecture</h2>
<h3>What is Event-Driven?</h3>
<p>Instead of waiting for things to happen, Node.js <strong>listens</strong> for events and responds.</p>
<h3>The Analogy</h3>
<p><strong>Synchronous (traditional servers):</strong></p>
<p>A waiter takes your order, goes to the kitchen, waits for the food, comes back, goes to the next customer.</p>
<p><strong>Event-Driven (Node.js):</strong></p>
<p>A waiter takes your order, puts it in a queue, serves other customers, and comes back when your food is ready.</p>
<p>More efficient.</p>
<h3>Example: Reading a File</h3>
<p><strong>Traditional approach (blocking):</strong></p>
<pre><code class="language-javascript">// This makes the server WAIT
const data = fs.readFileSync("large-file.txt");
console.log(data);
// Server is blocked until file is read
</code></pre>
<p><strong>Node.js approach (event-driven):</strong></p>
<pre><code class="language-javascript">// This doesn't block the server
fs.readFile("large-file.txt", (err, data) =&gt; {
  console.log(data);
});
// Server continues handling other requests
</code></pre>
<p>Node.js doesn't wait. It does other things and comes back when the file is ready.</p>
<h3>Why This Matters</h3>
<p>One Node.js server can handle <strong>thousands of requests</strong> without blocking, because it doesn't wait for operations to finish.</p>
<pre><code class="language-plaintext">Traditional Server (PHP/Java)
Request 1 → ⏳ waiting for database → Response
Request 2 → queued behind request 1
Request 3 → queued behind request 2

Node.js Server
Request 1 → database query (no wait)
Request 2 → database query (no wait)
Request 3 → database query (no wait)
Responses come back as each finishes
</code></pre>
<p>Much more efficient.</p>
<hr />
<h2>Node.js Runtime Architecture Overview</h2>
<pre><code class="language-plaintext">Node.js Runtime
  |
  ├─ V8 Engine
  |   └─ Executes JavaScript code
  |
  ├─ libuv (Library)
  |   ├─ Event loop
  |   ├─ Thread pool
  |   └─ Async I/O
  |
  ├─ Core Modules
  |   ├─ fs (files)
  |   ├─ http (server)
  |   ├─ os (system)
  |   └─ path (routing)
  |
  └─ npm (Package Manager)
      └─ Access to millions of libraries
</code></pre>
<p>The key: <strong>V8 executes your code, libuv handles async operations</strong>.</p>
<hr />
<h2>Real-World Use Cases of Node.js</h2>
<h3>1. Web Servers</h3>
<pre><code class="language-javascript">const http = require("http");

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

server.listen(3000);
</code></pre>
<p>Build APIs and websites. Simple and fast.</p>
<h3>2. Real-Time Applications</h3>
<p>Companies like <strong>Slack, Discord, Trello</strong> use Node.js for real-time features.</p>
<pre><code class="language-javascript">// WebSocket: real-time communication
socket.on("message", (data) =&gt; {
  broadcast(data);  // Send to all users instantly
});
</code></pre>
<p>Event-driven architecture is perfect for real-time.</p>
<h3>3. Building CLI Tools</h3>
<p>Create command-line tools for developers:</p>
<pre><code class="language-javascript">// npm, ESLint, Webpack, Prettier are all Node.js tools
const args = process.argv;
console.log("Arguments:", args);
</code></pre>
<h3>4. Data Processing &amp; Streaming</h3>
<p>Process large files without loading everything into memory:</p>
<pre><code class="language-javascript">const fs = require("fs");

fs.createReadStream("huge-file.csv")
  .pipe(processStream)
  .pipe(fs.createWriteStream("output.csv"));
</code></pre>
<p>Handle terabytes of data efficiently.</p>
<h3>5. IoT &amp; Embedded Systems</h3>
<p>Node.js runs on Raspberry Pi and IoT devices.</p>
<pre><code class="language-javascript">// Read sensor data
const sensorData = getSensorReading();
sendToCloud(sensorData);
</code></pre>
<h3>6. Building Microservices</h3>
<p>Netflix, LinkedIn, and Uber use Node.js for microservices.</p>
<pre><code class="language-javascript">// Small, focused services
app.post("/users", createUser);
app.get("/users/:id", getUser);
app.delete("/users/:id", deleteUser);
</code></pre>
<p>Each service is independent. Easy to scale.</p>
<hr />
<h2>Node.js vs Traditional Backend Languages</h2>
<h3>JavaScript (Node.js)</h3>
<p>Pros: One language for frontend and backend, event-driven and non-blocking, fast to write, perfect for real-time apps.</p>
<p>Cons: Single-threaded (traditionally), less suitable for CPU-intensive tasks.</p>
<h3>PHP</h3>
<p>Pros: Easy to learn, great for beginners.</p>
<p>Cons: Blocks per request (slower), no real-time support, poor for modern apps.</p>
<h3>Java</h3>
<p>Pros: Fast compiled language, mature ecosystem, good for enterprise.</p>
<p>Cons: Verbose and slow to write, requires more resources, steeper learning curve.</p>
<h3>Python</h3>
<p>Pros: Easy to read, great for AI and data science, large ecosystem.</p>
<p>Cons: Slow (interpreted), not ideal for real-time, multiple competing frameworks.</p>
<h3>Node.js Sweet Spot</h3>
<pre><code class="language-plaintext">Real-Time Apps     ← Node.js wins
APIs &amp; Servers     ← Node.js wins
CLI Tools          ← Node.js wins
Microservices      ← Node.js wins
Data Processing    ← Node.js strong

CPU-Intensive Work ← Java/Python better
Enterprise Systems ← Java better
</code></pre>
<p>Node.js excels at <strong>I/O-intensive</strong> applications (network, database, file operations). It's less ideal for <strong>CPU-intensive</strong> work (heavy calculations, image processing).</p>
<hr />
<h2>Why Developers Adopted Node.js</h2>
<h3>The Three Reasons</h3>
<p><strong>1. One Language Everywhere</strong></p>
<pre><code class="language-javascript">// Frontend
const user = { name: "Alice" };
document.getElementById("name").textContent = user.name;

// Backend (same JavaScript!)
const user = { name: "Alice" };
res.json(user);
</code></pre>
<p>Frontend developers could now write backend code without learning Java or PHP.</p>
<p><strong>2. Non-Blocking, Event-Driven</strong></p>
<p>One Node.js server can handle more requests than one PHP server because it doesn't block on I/O operations.</p>
<p><strong>3. Perfect for Modern Apps</strong></p>
<ul>
<li>Real-time features (chat, notifications)</li>
<li>Microservices architecture</li>
<li>Mobile APIs</li>
<li>WebSockets</li>
<li>Streaming data</li>
</ul>
<p>Node.js was designed for these use cases.</p>
<h3>The Tipping Point (2012-2015)</h3>
<p>npm grew. Libraries exploded. Companies started using Node.js in production.</p>
<p>Today, Node.js powers <strong>thousands of companies</strong>.</p>
<hr />
<h2>Browser JS vs Server JS: Execution Comparison</h2>
<pre><code class="language-plaintext">Browser Execution
  |
  ├─ User opens website
  ├─ Browser downloads HTML + JavaScript
  ├─ V8 engine parses JavaScript
  ├─ DOM is built
  ├─ User interacts (click, type)
  ├─ JavaScript responds to events
  └─ Page updates, render

Node.js Execution
  |
  ├─ Developer starts server
  ├─ Node.js loads JavaScript files
  ├─ V8 engine parses JavaScript
  ├─ Server starts listening for requests
  ├─ Client sends HTTP request
  ├─ JavaScript handles request
  ├─ Database query runs (non-blocking)
  ├─ Response is sent back
  └─ Server continues listening
</code></pre>
<p>Same engine (V8). Different triggers and APIs.</p>
<hr />
<h2>Simple Node.js Server Example</h2>
<pre><code class="language-javascript">const http = require("http");

// Create server
const server = http.createServer((req, res) =&gt; {
  // req = incoming request
  // res = response to send
  
  if (req.url === "/") {
    res.writeHead(200);
    res.write("Welcome to Node.js!");
    res.end();
  } else if (req.url === "/about") {
    res.writeHead(200);
    res.write("This is the about page");
    res.end();
  } else {
    res.writeHead(404);
    res.write("Page not found");
    res.end();
  }
});

// Listen on port 3000
server.listen(3000, () =&gt; {
  console.log("Server running on http://localhost:3000");
});
</code></pre>
<p>Run it:</p>
<pre><code class="language-bash">node server.js
# Server running on http://localhost:3000
</code></pre>
<p>Visit <code>http://localhost:3000</code> in your browser. You'll see "Welcome to Node.js!"</p>
<hr />
<h2>Key Differences Summarized</h2>
<table>
<thead>
<tr>
<th>Aspect</th>
<th>Browser JS</th>
<th>Node.js</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Engine</strong></td>
<td>V8 (same)</td>
<td>V8 (same)</td>
</tr>
<tr>
<td><strong>APIs</strong></td>
<td>DOM, document, window</td>
<td>fs, http, os</td>
</tr>
<tr>
<td><strong>Use Case</strong></td>
<td>User interaction</td>
<td>Server operations</td>
</tr>
<tr>
<td><strong>Lifespan</strong></td>
<td>Page load to close</td>
<td>Runs indefinitely</td>
</tr>
<tr>
<td><strong>Access</strong></td>
<td>Can't touch disk</td>
<td>Full disk/network access</td>
</tr>
<tr>
<td><strong>Blocking</strong></td>
<td>Some (user doesn't mind)</td>
<td>Should be non-blocking</td>
</tr>
<tr>
<td><strong>Modules</strong></td>
<td>script tags</td>
<td>require() / import</td>
</tr>
</tbody></table>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Understand the difference:</strong></p>
<pre><code class="language-javascript">// Why does this work in Browser but NOT in Node.js?
document.getElementById("button");

// Why does this work in Node.js but NOT in Browser?
fs.readFileSync("/etc/passwd");
</code></pre>
<p><strong>2. Create a simple server:</strong></p>
<pre><code class="language-javascript">// Create an http server
// Listen on port 3000
// Respond with "Hello Node.js"
// Test with curl or browser
</code></pre>
<p><strong>3. Explore the event-driven model:</strong></p>
<pre><code class="language-javascript">// Use fs.readFile (async, non-blocking)
// Use a callback function
// Console.log the file contents
// Understand why it doesn't block
</code></pre>
<p><strong>4. Build a multi-route server:</strong></p>
<pre><code class="language-javascript">// Create routes for:
// GET / → "Home"
// GET /about → "About page"
// GET /users → "Users list"
// GET /404 → "Not found"
// Test each route
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><strong>Node.js</strong> is a runtime that executes JavaScript outside the browser.</li>
<li><strong>JavaScript</strong> was browser-only because it was designed for user interactions and DOM manipulation.</li>
<li>Node.js uses the same <strong>V8 engine</strong> as Chrome but with different APIs for server tasks.</li>
<li><strong>Runtime</strong> is the environment where code runs; <strong>programming language</strong> is the syntax.</li>
<li>Node.js has <strong>no DOM, document, or window objects</strong> because it runs on servers, not browsers.</li>
<li><strong>V8</strong> is Google's JavaScript engine that compiles JS to machine code.</li>
<li>Node.js uses <strong>event-driven, non-blocking I/O</strong> to handle thousands of concurrent requests efficiently.</li>
<li><strong>libuv</strong> handles the event loop and async operations behind the scenes.</li>
<li>Node.js excels at <strong>I/O-intensive</strong> applications: APIs, real-time apps, microservices, CLI tools.</li>
<li>Node.js is <strong>not ideal</strong> for CPU-intensive work (use Python or Java instead).</li>
<li>Browser JS responds to <strong>user events</strong> (clicks); Server JS responds to <strong>network events</strong> (requests).</li>
<li>One language for frontend and backend is Node.js's killer feature.</li>
</ul>
<p>Node.js turned JavaScript into a full-stack language.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[JWT Authentication in Node.js Explained Simply
]]></title><description><![CDATA[Apps need to know who's using them. But checking a database on every request is slow. JWT lets you prove who you are with a signed token the server can verify instantly.
This is about understanding JW]]></description><link>https://blog.harshx.in/jwt-authentication-in-node-js</link><guid isPermaLink="true">https://blog.harshx.in/jwt-authentication-in-node-js</guid><category><![CDATA[Node.js]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 10:55:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/52378036-5a51-463e-ac1d-c5fe0a35c139.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Apps need to know who's using them. But checking a database on every request is slow. JWT lets you prove who you are with a signed token the server can verify instantly.</p>
<p>This is about understanding JWT and building login systems without session databases.</p>
<hr />
<h2>What Authentication Means</h2>
<p>Authentication answers: "Who are you?"</p>
<h3>Real Example</h3>
<p>Checking into a hotel: you show an ID once, and they don't check the guest list every time you walk in. The ID is your proof.</p>
<p>Apps work the same way.</p>
<h3>Without Authentication</h3>
<pre><code class="language-javascript">app.get("/profile", (req, res) =&gt; {
  res.json({ message: "Anyone can access this" });
});
</code></pre>
<p>No protection.</p>
<h3>With Authentication</h3>
<pre><code class="language-javascript">app.get("/profile", (req, res) =&gt; {
  if (!req.user) {
    return res.status(401).json({ error: "Not authenticated" });
  }
  res.json({ message: `Hello ${req.user.name}` });
});
</code></pre>
<p>Only authenticated users see it.</p>
<hr />
<h2>What JWT Is</h2>
<p>JWT (JSON Web Token) is a token that represents a user's identity.</p>
<h3>The Concept</h3>
<ol>
<li>User logs in</li>
<li>Server creates a token containing their info</li>
<li>Server sends the token</li>
<li>User sends the token with every request</li>
<li>Server verifies the token (no database needed)</li>
</ol>
<p>The token itself proves who they are.</p>
<h3>Simple Analogy</h3>
<p>Concert wristband: instead of the venue checking a list every time you enter, you wear a wristband proving you're authorized. The wristband is the proof.</p>
<p>JWT is like that wristband for API requests.</p>
<h3>JWT vs Sessions</h3>
<table>
<thead>
<tr>
<th>Sessions</th>
<th>JWT</th>
</tr>
</thead>
<tbody><tr>
<td>Stored on server</td>
<td>Stored on client</td>
</tr>
<tr>
<td>Database lookup</td>
<td>Token contains data</td>
</tr>
<tr>
<td>One server only</td>
<td>Works across servers</td>
</tr>
<tr>
<td>Can revoke immediately</td>
<td>Valid until expiration</td>
</tr>
</tbody></table>
<hr />
<h2>Structure of a JWT</h2>
<p>A JWT has three parts: <code>header.payload.signature</code></p>
<h3>Part 1: Header</h3>
<pre><code class="language-javascript">{
  "alg": "HS256",    // Algorithm
  "typ": "JWT"       // Type
}
</code></pre>
<p>Base64 encoded: <code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9</code></p>
<h3>Part 2: Payload</h3>
<pre><code class="language-javascript">{
  "userId": 1,
  "email": "alice@example.com",
  "name": "Alice",
  "iat": 1234567890,    // Issued at
  "exp": 1234571490     // Expires at
}
</code></pre>
<p>Base64 encoded: <code>eyJ1c2VySWQiOjEsImVtYWlsIjoiYWxpY2VAZXhhbXBsZS5jb20ifQ</code></p>
<h3>Part 3: Signature</h3>
<p>Server signs the header and payload:</p>
<pre><code>HMACSHA256(
  base64(header) + "." + base64(payload),
  "secret-key"
)
</code></pre>
<p>Result: <code>SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c</code></p>
<h3>Complete Token</h3>
<pre><code>eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjE...SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
</code></pre>
<p>Three parts separated by dots.</p>
<h3>Why the Signature Matters</h3>
<p>It proves the token hasn't been tampered with:</p>
<pre><code class="language-plaintext">Valid token: signature matches
Tampered token: signature doesn't match → rejected
</code></pre>
<hr />
<h2>JWT Token Structure Visualization</h2>
<pre><code class="language-plaintext">JWT Token
  |
  ├─ Header (base64)
  |   ├─ Algorithm: HS256
  |   └─ Type: JWT
  |
  ├─ Payload (base64)
  |   ├─ userId: 1
  |   ├─ email: alice@example.com
  |   ├─ name: Alice
  |   ├─ iat: 1234567890
  |   └─ exp: 1234571490
  |
  └─ Signature (HMAC)
      └─ Hash of header + payload with secret
</code></pre>
<p>The server can read the payload without a database because it's right there in the token.</p>
<hr />
<h2>Login Flow Using JWT</h2>
<h3>Step 1: User Logs In</h3>
<pre><code class="language-javascript">app.post("/login", (req, res) =&gt; {
  const { email, password } = req.body;
  const user = users.find(u =&gt; u.email === email);
  
  if (!user || user.password !== password) {
    return res.status(401).json({ error: "Invalid credentials" });
  }
  
  // Credentials valid
  res.json({ message: "Login successful" });
});
</code></pre>
<h3>Step 2: Server Creates JWT</h3>
<pre><code class="language-javascript">const jwt = require("jsonwebtoken");
const SECRET = "your-secret-key";

app.post("/login", (req, res) =&gt; {
  const { email, password } = req.body;
  const user = users.find(u =&gt; u.email === email);
  
  if (!user || user.password !== password) {
    return res.status(401).json({ error: "Invalid credentials" });
  }
  
  // Create token
  const token = jwt.sign(
    { userId: user.id, email: user.email, name: user.name },
    SECRET,
    { expiresIn: "24h" }
  );
  
  res.json({ token });
});
</code></pre>
<p>Token contains user info and expires in 24 hours.</p>
<h3>Step 3: Client Stores Token</h3>
<pre><code class="language-javascript">// After login, client stores token
localStorage.setItem("token", token);
</code></pre>
<h3>Step 4: Client Sends Token With Requests</h3>
<pre><code class="language-javascript">// Every request includes the token
const token = localStorage.getItem("token");

fetch("http://localhost:3000/profile", {
  headers: {
    "Authorization": `Bearer ${token}`
  }
});
</code></pre>
<h3>Step 5: Server Verifies Token</h3>
<pre><code class="language-javascript">app.get("/profile", (req, res) =&gt; {
  const token = req.headers.authorization?.split(" ")[1];
  
  if (!token) {
    return res.status(401).json({ error: "No token" });
  }
  
  try {
    const decoded = jwt.verify(token, SECRET);
    res.json({ message: `Hello ${decoded.name}` });
  } catch (error) {
    res.status(401).json({ error: "Invalid token" });
  }
});
</code></pre>
<p>No database needed. The token proves who they are.</p>
<hr />
<h2>JWT Login Authentication Flow</h2>
<pre><code class="language-plaintext">User sends login request
(email + password)
      |
      v
Server finds user in database
      |
      v
Server checks password
      |
      ├─ Wrong: send error
      └─ Correct: continue
      |
      v
Server creates JWT token
(contains user info)
      |
      v
Server sends token to client
      |
      v
Client stores token
(localStorage, sessionStorage, etc)
      |
      v
User makes API request
(includes token in Authorization header)
      |
      v
Server verifies token signature
      |
      ├─ Invalid: reject (401)
      └─ Valid: continue
      |
      v
Request allowed, response sent
</code></pre>
<hr />
<h2>Sending Token With Requests</h2>
<h3>In HTTP Header (Standard)</h3>
<pre><code class="language-javascript">// Client side
const token = localStorage.getItem("token");

fetch("http://localhost:3000/profile", {
  headers: {
    "Authorization": `Bearer ${token}`
  }
});
</code></pre>
<p>This is the standard approach.</p>
<h3>In Cookie</h3>
<p>Alternative (automatically sent):</p>
<pre><code class="language-javascript">// Server side
res.cookie("token", token, {
  httpOnly: true,
  secure: true,
  maxAge: 24 * 60 * 60 * 1000
});
</code></pre>
<h3>In Query String</h3>
<p>Not recommended (exposes token in logs):</p>
<pre><code class="language-javascript">fetch("http://localhost:3000/profile?token=" + token);
</code></pre>
<p>The header approach is best.</p>
<hr />
<h2>Protecting Routes Using Tokens</h2>
<h3>Token Verification Middleware</h3>
<pre><code class="language-javascript">function verifyToken(req, res, next) {
  const token = req.headers.authorization?.split(" ")[1];
  
  if (!token) {
    return res.status(401).json({ error: "No token" });
  }
  
  try {
    const decoded = jwt.verify(token, SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    res.status(401).json({ error: "Invalid token" });
  }
}
</code></pre>
<h3>Apply to Routes</h3>
<pre><code class="language-javascript">// Protected route
app.get("/profile", verifyToken, (req, res) =&gt; {
  res.json({ 
    message: `Hello ${req.user.name}`,
    user: req.user
  });
});

// Another protected route
app.get("/posts", verifyToken, (req, res) =&gt; {
  res.json({ posts: "User's posts" });
});

// Public route (no middleware)
app.get("/public", (req, res) =&gt; {
  res.json({ message: "Anyone can see this" });
});
</code></pre>
<p>The middleware checks the token before the handler runs.</p>
<h3>Admin-Only Route</h3>
<pre><code class="language-javascript">function requireAdmin(req, res, next) {
  if (req.user.role !== "admin") {
    return res.status(403).json({ error: "Admin only" });
  }
  next();
}

app.delete("/users/:id", verifyToken, requireAdmin, (req, res) =&gt; {
  res.json({ message: "User deleted" });
});
</code></pre>
<hr />
<h2>Complete Login Example</h2>
<pre><code class="language-javascript">const express = require("express");
const jwt = require("jsonwebtoken");

const app = express();
app.use(express.json());

const SECRET = "your-secret-key";

// In-memory user store
const users = [
  { id: 1, email: "alice@example.com", password: "password123", name: "Alice" },
  { id: 2, email: "bob@example.com", password: "password456", name: "Bob" }
];

// Login endpoint
app.post("/login", (req, res) =&gt; {
  const { email, password } = req.body;
  
  // Find user
  const user = users.find(u =&gt; u.email === email);
  
  // Check password
  if (!user || user.password !== password) {
    return res.status(401).json({ error: "Invalid credentials" });
  }
  
  // Create token
  const token = jwt.sign(
    { userId: user.id, email: user.email, name: user.name },
    SECRET,
    { expiresIn: "24h" }
  );
  
  res.json({ token });
});

// Verify token middleware
function verifyToken(req, res, next) {
  const token = req.headers.authorization?.split(" ")[1];
  
  if (!token) {
    return res.status(401).json({ error: "No token" });
  }
  
  try {
    const decoded = jwt.verify(token, SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    res.status(401).json({ error: "Invalid token" });
  }
}

// Protected route
app.get("/profile", verifyToken, (req, res) =&gt; {
  res.json({ message: `Hello ${req.user.name}`, user: req.user });
});

// Public route
app.get("/public", (req, res) =&gt; {
  res.json({ message: "Public data" });
});

app.listen(3000, () =&gt; {
  console.log("Server running on http://localhost:3000");
});
</code></pre>
<h3>Test It</h3>
<pre><code class="language-bash"># Login
curl -X POST http://localhost:3000/login \
  -H "Content-Type: application/json" \
  -d '{"email":"alice@example.com","password":"password123"}'

# Response: {"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}

# Access protected route with token
curl http://localhost:3000/profile \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# Response: {"message":"Hello Alice","user":{"userId":1,...}}
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Create a login endpoint:</strong></p>
<pre><code class="language-javascript">// Receive email and password
// Find user in array
// Create JWT if credentials valid
// Return token
</code></pre>
<p><strong>2. Build token verification middleware:</strong></p>
<pre><code class="language-javascript">// Extract token from Authorization header
// Verify signature with jwt.verify()
// Store decoded user in req.user
// Call next() if valid
</code></pre>
<p><strong>3. Protect a route:</strong></p>
<pre><code class="language-javascript">// Apply verifyToken middleware to a route
// Route should access req.user
// Test with curl including token
</code></pre>
<p><strong>4. Handle token expiration:</strong></p>
<pre><code class="language-javascript">// Set expiresIn to "1h"
// Try accessing route after expiration
// See "invalid token" error
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Authentication</strong> proves who someone is.</p>
</li>
<li><p><strong>JWT</strong> is a token containing user info, signed by the server.</p>
</li>
<li><p>JWT has three parts: <code>header.payload.signature</code></p>
</li>
<li><p><strong>Header</strong> specifies the algorithm.</p>
</li>
<li><p><strong>Payload</strong> contains user data.</p>
</li>
<li><p><strong>Signature</strong> proves the token hasn't been tampered with.</p>
</li>
<li><p>Login: receive credentials → verify → create token → send to client.</p>
</li>
<li><p>Clients send the token in the <code>Authorization</code> header.</p>
</li>
<li><p>Servers verify the token's signature, no database needed.</p>
</li>
<li><p>Protect routes by checking the token before allowing access.</p>
</li>
<li><p>JWT is stateless: the token proves who the user is.</p>
</li>
</ul>
<p>JWT makes authentication simple and scalable.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile.
🔗 Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Creating Routes and Handling Requests with Express
]]></title><description><![CDATA[Raw Node.js HTTP servers work, but they're verbose. You spend time parsing URLs and handling different HTTP methods instead of building your app. Express removes that noise.
This is about how Express ]]></description><link>https://blog.harshx.in/creating-routes-and-handling-requests-with-express</link><guid isPermaLink="true">https://blog.harshx.in/creating-routes-and-handling-requests-with-express</guid><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 10:41:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/09b38175-ddbd-4593-9f76-8a25d0a65ee4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Raw Node.js HTTP servers work, but they're verbose. You spend time parsing URLs and handling different HTTP methods instead of building your app. Express removes that noise.</p>
<p>This is about how Express simplifies server building and lets you focus on routes and logic.</p>
<hr />
<h2>What Express.js Is</h2>
<p>Express is a framework for building web servers in Node.js. It handles routing, middleware, and request/response management so you don't have to.</p>
<h3>Without Express (Raw Node.js)</h3>
<pre><code class="language-javascript">const http = require("http");

const server = http.createServer((req, res) =&gt; {
  if (req.method === "GET" &amp;&amp; req.url === "/") {
    res.writeHead(200, { "Content-Type": "text/plain" });
    res.end("Home page");
  } else if (req.method === "GET" &amp;&amp; req.url === "/about") {
    res.writeHead(200, { "Content-Type": "text/plain" });
    res.end("About page");
  } else {
    res.writeHead(404, { "Content-Type": "text/plain" });
    res.end("Not found");
  }
});

server.listen(3000);
</code></pre>
<p>Lots of boilerplate for just two routes.</p>
<h3>With Express</h3>
<pre><code class="language-javascript">const express = require("express");
const app = express();

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

app.get("/about", (req, res) =&gt; {
  res.send("About page");
});

app.listen(3000);
</code></pre>
<p>Same functionality, much cleaner.</p>
<hr />
<h2>Why Express Simplifies Node.js Development</h2>
<h3>1. Routing Is Built-In</h3>
<p>Express makes routing straightforward:</p>
<pre><code class="language-javascript">app.get("/users", (req, res) =&gt; {
  // Handle GET /users
});

app.post("/users", (req, res) =&gt; {
  // Handle POST /users
});

app.delete("/users/:id", (req, res) =&gt; {
  // Handle DELETE /users/123
});
</code></pre>
<p>Raw Node.js requires manual URL parsing.</p>
<h3>2. Request/Response Helpers</h3>
<p>Express provides convenience methods:</p>
<pre><code class="language-javascript">res.json({ data: "value" });      // Send JSON
res.send("text response");        // Send text
res.status(404).send("Not found"); // Set status
</code></pre>
<p>Raw Node.js requires manual header management.</p>
<h3>3. URL Parameters and Query Strings</h3>
<p>Automatic parsing:</p>
<pre><code class="language-javascript">app.get("/users/:id", (req, res) =&gt; {
  const userId = req.params.id;  // From /users/123
});

app.get("/search", (req, res) =&gt; {
  const query = req.query.q;  // From /search?q=hello
});
</code></pre>
<p>Raw Node.js requires string parsing.</p>
<hr />
<h2>Creating Your First Express Server</h2>
<h3>Step 1: Install Express</h3>
<pre><code class="language-bash">npm install express
</code></pre>
<h3>Step 2: Create the Server</h3>
<pre><code class="language-javascript">const express = require("express");
const app = express();

// Your routes here

app.listen(3000, () =&gt; {
  console.log("Server running on http://localhost:3000");
});
</code></pre>
<p>That's the minimal setup. Just a few lines.</p>
<h3>Step 3: Add Routes</h3>
<pre><code class="language-javascript">const express = require("express");
const app = express();

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

app.listen(3000, () =&gt; {
  console.log("Server running on http://localhost:3000");
});
</code></pre>
<p>Now your server responds to GET requests at the root path.</p>
<h3>Test It</h3>
<pre><code class="language-bash">node server.js
# Server running on http://localhost:3000

# In another terminal
curl http://localhost:3000
# Hello, World!
</code></pre>
<p>It works immediately.</p>
<hr />
<h2>Request → Route Handler → Response Flow</h2>
<pre><code class="language-plaintext">Browser sends request
  |
  v
Express receives request
  |
  v
Matches URL to a route
  |
  v
Route handler function called
  |
  ├─ req: request object (data from browser)
  └─ res: response object (send data back)
  |
  v
Handler uses res.send() or res.json()
  |
  v
Response sent back to browser
  |
  v
Browser displays it
</code></pre>
<p>Each request goes through this cycle.</p>
<hr />
<h2>Handling GET Requests</h2>
<p>GET requests retrieve data. They're read-only.</p>
<h3>Basic GET Route</h3>
<pre><code class="language-javascript">app.get("/", (req, res) =&gt; {
  res.send("Home page");
});
</code></pre>
<p>Visiting the root URL triggers this handler.</p>
<h3>GET With URL Parameters</h3>
<pre><code class="language-javascript">app.get("/users/:id", (req, res) =&gt; {
  const userId = req.params.id;
  res.send(`User ID: ${userId}`);
});

// /users/5 → "User ID: 5"
// /users/123 → "User ID: 123"
</code></pre>
<p>The <code>:id</code> is a variable in the URL.</p>
<h3>GET With Query Strings</h3>
<pre><code class="language-javascript">app.get("/search", (req, res) =&gt; {
  const query = req.query.q;
  res.send(`Searching for: ${query}`);
});

// /search?q=javascript → "Searching for: javascript"
</code></pre>
<p>Query strings come after the <code>?</code>.</p>
<h3>Real Example: User Endpoint</h3>
<pre><code class="language-javascript">const users = [
  { id: 1, name: "Alice" },
  { id: 2, name: "Bob" }
];

app.get("/users", (req, res) =&gt; {
  res.json(users);
});

app.get("/users/:id", (req, res) =&gt; {
  const user = users.find(u =&gt; u.id == req.params.id);
  if (user) {
    res.json(user);
  } else {
    res.status(404).send("User not found");
  }
});
</code></pre>
<p>Requests:</p>
<ul>
<li><code>GET /users</code> → all users</li>
<li><code>GET /users/1</code> → user 1</li>
<li><code>GET /users/999</code> → 404</li>
</ul>
<hr />
<h2>Handling POST Requests</h2>
<p>POST requests send data to the server.</p>
<h3>Basic POST Route</h3>
<pre><code class="language-javascript">app.post("/users", (req, res) =&gt; {
  res.send("User created");
});
</code></pre>
<p>A POST to <code>/users</code> triggers this handler.</p>
<h3>POST With Data</h3>
<p>Add middleware to parse the body:</p>
<pre><code class="language-javascript">const express = require("express");
const app = express();

app.use(express.json());

app.post("/users", (req, res) =&gt; {
  const name = req.body.name;
  res.json({ message: "User created", name });
});
</code></pre>
<p>Now <code>req.body</code> contains the request data.</p>
<h3>Real Example: Creating a Resource</h3>
<pre><code class="language-javascript">const express = require("express");
const app = express();

app.use(express.json());

let users = [{ id: 1, name: "Alice" }];

app.post("/users", (req, res) =&gt; {
  const newUser = {
    id: users.length + 1,
    name: req.body.name
  };
  users.push(newUser);
  res.status(201).json(newUser);
});
</code></pre>
<p>Test it:</p>
<pre><code class="language-bash">curl -X POST http://localhost:3000/users \
  -H "Content-Type: application/json" \
  -d '{"name":"David"}'

# Response: {"id":2,"name":"David"}
</code></pre>
<hr />
<h2>Sending Responses</h2>
<p>Express provides multiple ways to send responses back.</p>
<h3>Plain Text</h3>
<pre><code class="language-javascript">app.get("/text", (req, res) =&gt; {
  res.send("Plain text response");
});
</code></pre>
<h3>JSON</h3>
<pre><code class="language-javascript">app.get("/json", (req, res) =&gt; {
  res.json({ message: "Hello", value: 42 });
});
</code></pre>
<h3>HTML</h3>
<pre><code class="language-javascript">app.get("/html", (req, res) =&gt; {
  res.send("&lt;h1&gt;Hello World&lt;/h1&gt;");
});
</code></pre>
<h3>With Status Code</h3>
<pre><code class="language-javascript">app.post("/created", (req, res) =&gt; {
  res.status(201).json({ id: 1 });
});

app.get("/not-found", (req, res) =&gt; {
  res.status(404).send("Not found");
});

app.get("/error", (req, res) =&gt; {
  res.status(500).send("Server error");
});
</code></pre>
<p>Status codes tell the browser what happened:</p>
<ul>
<li>200: OK</li>
<li>201: Created</li>
<li>404: Not found</li>
<li>500: Server error</li>
</ul>
<h3>Redirect</h3>
<pre><code class="language-javascript">app.get("/old-page", (req, res) =&gt; {
  res.redirect("/new-page");
});
</code></pre>
<hr />
<h2>Complete Example: Simple API</h2>
<pre><code class="language-javascript">const express = require("express");
const app = express();

app.use(express.json());

// In-memory data store
let posts = [
  { id: 1, title: "First Post", body: "Hello" },
  { id: 2, title: "Second Post", body: "World" }
];

// GET all posts
app.get("/posts", (req, res) =&gt; {
  res.json(posts);
});

// GET one post
app.get("/posts/:id", (req, res) =&gt; {
  const post = posts.find(p =&gt; p.id == req.params.id);
  if (post) {
    res.json(post);
  } else {
    res.status(404).json({ error: "Post not found" });
  }
});

// CREATE a post
app.post("/posts", (req, res) =&gt; {
  const newPost = {
    id: posts.length + 1,
    title: req.body.title,
    body: req.body.body
  };
  posts.push(newPost);
  res.status(201).json(newPost);
});

// UPDATE a post
app.put("/posts/:id", (req, res) =&gt; {
  const post = posts.find(p =&gt; p.id == req.params.id);
  if (post) {
    post.title = req.body.title || post.title;
    post.body = req.body.body || post.body;
    res.json(post);
  } else {
    res.status(404).json({ error: "Post not found" });
  }
});

// DELETE a post
app.delete("/posts/:id", (req, res) =&gt; {
  const index = posts.findIndex(p =&gt; p.id == req.params.id);
  if (index !== -1) {
    const deleted = posts.splice(index, 1);
    res.json(deleted[0]);
  } else {
    res.status(404).json({ error: "Post not found" });
  }
});

app.listen(3000, () =&gt; {
  console.log("API running on http://localhost:3000");
});
</code></pre>
<p>This API handles create, read, update, and delete operations.</p>
<hr />
<h2>Express Routing Structure</h2>
<pre><code class="language-plaintext">app
  |
  ├─ app.get("/path", handler)
  ├─ app.post("/path", handler)
  ├─ app.put("/path", handler)
  ├─ app.delete("/path", handler)
  |
  └─ app.listen(port)

Each route:
  path: URL to match
  handler: function to run
    req: incoming request
    res: outgoing response
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Create a basic server:</strong></p>
<pre><code class="language-javascript">const express = require("express");
const app = express();

// Create GET / endpoint that returns "Hello"
// Create GET /about endpoint that returns "About page"

app.listen(3000);
</code></pre>
<p><strong>2. Handle URL parameters:</strong></p>
<pre><code class="language-javascript">// Create GET /greet/:name that returns "Hello, {name}"
// Example: /greet/alice → "Hello, alice"
</code></pre>
<p><strong>3. Handle POST requests:</strong></p>
<pre><code class="language-javascript">// Parse JSON
// Create POST /data that receives { message: "..." }
// Return { received: message }
</code></pre>
<p><strong>4. Build a simple resource API:</strong></p>
<pre><code class="language-javascript">// Create an array of items
// GET /items → return all
// GET /items/:id → return one
// POST /items → create new
// DELETE /items/:id → delete one
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p>Express is a framework for building web servers in Node.js.</p>
</li>
<li><p>Routes are defined with <code>app.get()</code>, <code>app.post()</code>, <code>app.put()</code>, <code>app.delete()</code>.</p>
</li>
<li><p>URL parameters come from <code>req.params</code>.</p>
</li>
<li><p>Query strings come from <code>req.query</code>.</p>
</li>
<li><p>POST data comes from <code>req.body</code> (with <code>express.json()</code> middleware).</p>
</li>
<li><p>Responses are sent with <code>res.send()</code>, <code>res.json()</code>, or <code>res.status()</code>.</p>
</li>
<li><p>Status codes indicate what happened (200, 201, 404, 500).</p>
</li>
<li><p>Express removes boilerplate compared to raw Node.js.</p>
</li>
<li><p>A single <code>app.listen()</code> starts the server.</p>
</li>
<li><p>Routing in Express is simple and readable.</p>
</li>
</ul>
<p>Express makes building web servers straightforward. Focus on routes and logic, not HTTP boilerplate.</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile.
🔗 Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Synchronous vs Asynchronous JavaScript
]]></title><description><![CDATA[JavaScript runs code line by line. But you constantly need to wait for things: files to load, API responses to arrive, timers to finish. Blocking code would freeze everything. Asynchronous code keeps ]]></description><link>https://blog.harshx.in/synchronous-vs-asynchronous-javascript</link><guid isPermaLink="true">https://blog.harshx.in/synchronous-vs-asynchronous-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 10:37:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/b9eb874c-8388-4e71-a58d-3a5f8d840991.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>JavaScript runs code line by line. But you constantly need to wait for things: files to load, API responses to arrive, timers to finish. Blocking code would freeze everything. Asynchronous code keeps things moving.</p>
<p>This is the core difference between JavaScript that feels fast and JavaScript that feels broken.</p>
<hr />
<h2>What Synchronous Code Means</h2>
<p>Synchronous code runs line by line, in order. Each line waits for the previous one.</p>
<h3>Simple Example</h3>
<pre><code class="language-javascript">console.log("Line 1");
console.log("Line 2");
console.log("Line 3");

// Output:
// Line 1
// Line 2
// Line 3
</code></pre>
<p>One line, then the next. Straightforward.</p>
<h3>With Operations</h3>
<pre><code class="language-javascript">console.log("Start");
const sum = 5 + 3;
console.log("Sum:", sum);
console.log("Done");

// Output:
// Start
// Sum: 8
// Done
</code></pre>
<p>Each operation completes before moving on.</p>
<h3>Real Example: Reading a File</h3>
<pre><code class="language-javascript">const fs = require("fs");

console.log("Before");
const data = fs.readFileSync("data.txt", "utf8");
console.log("Data:", data);
console.log("After");

// Output:
// Before
// Data: (contents)
// After
</code></pre>
<p><code>readFileSync</code> blocks. The program waits for the file.</p>
<hr />
<h2>What Asynchronous Code Means</h2>
<p>Asynchronous code starts an operation but doesn't wait for it. It continues running and gets notified when the operation completes.</p>
<h3>Simple Example</h3>
<pre><code class="language-javascript">console.log("Start");

setTimeout(() =&gt; {
  console.log("After 2 seconds");
}, 2000);

console.log("End");

// Output:
// Start
// End
// (2 seconds pass)
// After 2 seconds
</code></pre>
<p>Notice: "End" prints before the timeout callback. JavaScript doesn't wait.</p>
<h3>How It Works</h3>
<pre><code class="language-plaintext">Time →
|
Start: console.log("Start") → prints immediately
  |
  ├─ setTimeout called (doesn't wait)
  |  └─ callback scheduled for later
  |
  ├─ console.log("End") → prints immediately
  |
  └─ (user continues using app)
  |
  (2 seconds pass)
  |
  └─ Callback fires: console.log("After 2 seconds")
  |
Done
</code></pre>
<p>JavaScript continues running while waiting for the timer.</p>
<h3>Real Example: API Request</h3>
<pre><code class="language-javascript">console.log("Fetching data...");

fetch("https://api.example.com/users/1")
  .then(response =&gt; response.json())
  .then(user =&gt; console.log("User:", user));

console.log("Request sent");

// Output:
// Fetching data...
// Request sent
// (network request happens)
// User: { id: 1, name: "Alice" }
</code></pre>
<p>The fetch doesn't block. JavaScript continues to "Request sent" before the data arrives.</p>
<hr />
<h2>Synchronous Execution Timeline</h2>
<pre><code class="language-plaintext">START
  |
  v
Execute Line 1
  |
  v
Execute Line 2
  |
  v
Execute Line 3
  |
  v
Execute Line 4
  |
  v
END

Strict top-to-bottom order
Each line waits for the previous to finish
</code></pre>
<h2>Asynchronous Task Queue Concept</h2>
<pre><code class="language-plaintext">START
  |
  v
Execute immediate code
  |
  ├─ Line 1: fetch("api")  → add to task queue
  |
  ├─ Line 2: console.log   → execute immediately
  |
  └─ Continue to END
  |
  v
QUEUE (waiting for data)
  |
  └─ fetch callback (waiting for response)
  |
  (when data arrives)
  |
  └─ Execute callback
  |
  v
END
</code></pre>
<hr />
<h2>Why JavaScript Needs Asynchronous Behavior</h2>
<h3>The Problem: Blocking Code</h3>
<p>Without async, waiting for data freezes everything:</p>
<pre><code class="language-javascript">// Synchronous read from network (hypothetical)
const userData = synchronousNetworkRead("https://api.example.com/user/1");
// User can't do anything while waiting. App is frozen.
</code></pre>
<p>If the network takes 5 seconds, the entire app is frozen for 5 seconds. Users can't click, scroll, or interact.</p>
<h3>The Solution: Asynchronous</h3>
<pre><code class="language-javascript">// Asynchronous read from network
fetch("https://api.example.com/user/1")
  .then(response =&gt; response.json())
  .then(user =&gt; console.log("User:", user));

// User can still click, scroll, and interact
// App remains responsive
</code></pre>
<p>The fetch starts, but JavaScript keeps running. Users can interact while waiting.</p>
<h3>Real-World Analogy</h3>
<p><strong>Synchronous (Restaurant):</strong>
You order food. You stand at the counter and don't move until your food is ready. Everyone behind you waits. Nothing else happens.</p>
<p><strong>Asynchronous (Pager):</strong>
You order food. You get a pager. You sit down and can relax, order drinks, chat. When food is ready, the pager buzzes. You go get it. Everyone can use the line for their own orders.</p>
<p>JavaScript uses the pager model.</p>
<hr />
<h2>Examples: API Calls</h2>
<h3>Synchronous Approach (Hypothetical)</h3>
<pre><code class="language-javascript">function getUserData(userId) {
  // This would freeze the app while waiting
  const user = synchronousAPICall(`/api/users/${userId}`);
  return user;
}

// User can't interact while waiting
const user = getUserData(1);
console.log("User:", user);
</code></pre>
<p>If the API takes 3 seconds, the app is frozen for 3 seconds.</p>
<h3>Asynchronous Approach (Real)</h3>
<pre><code class="language-javascript">function getUserData(userId) {
  return fetch(`/api/users/${userId}`)
    .then(response =&gt; response.json());
}

// App remains responsive
getUserData(1).then(user =&gt; {
  console.log("User:", user);
});

// This runs immediately, doesn't wait
console.log("Request started");
</code></pre>
<p>Output:</p>
<pre><code>Request started
(network happens)
User: { id: 1, name: "Alice" }
</code></pre>
<p>The app stays responsive.</p>
<h3>With Async/Await</h3>
<pre><code class="language-javascript">async function getUserData(userId) {
  const response = await fetch(`/api/users/${userId}`);
  const user = await response.json();
  return user;
}

async function main() {
  const user = await getUserData(1);
  console.log("User:", user);
}

main();
</code></pre>
<p>Same thing, more readable. App stays responsive.</p>
<hr />
<h2>Examples: Timers</h2>
<h3>Synchronous Wait (Not Built-In)</h3>
<p>JavaScript doesn't have a built-in synchronous wait, but you could simulate it:</p>
<pre><code class="language-javascript">function badWait(milliseconds) {
  const start = Date.now();
  while (Date.now() - start &lt; milliseconds) {
    // Do nothing, just burn CPU
  }
}

console.log("Start");
badWait(3000);  // Block for 3 seconds
console.log("After 3 seconds");
</code></pre>
<p>This blocks everything. Users can't interact. CPU spins uselessly.</p>
<h3>Asynchronous Wait (The Right Way)</h3>
<pre><code class="language-javascript">console.log("Start");

setTimeout(() =&gt; {
  console.log("After 3 seconds");
}, 3000);

console.log("I run immediately");

// Output:
// Start
// I run immediately
// (3 seconds pass)
// After 3 seconds
</code></pre>
<p>The app stays responsive. Users can interact while waiting.</p>
<h3>Real Scenario: Loading Multiple Files</h3>
<p><strong>Bad (Blocking):</strong></p>
<pre><code class="language-javascript">const fs = require("fs");

console.log("Start");
const file1 = fs.readFileSync("file1.txt");  // Waits
const file2 = fs.readFileSync("file2.txt");  // Waits
const file3 = fs.readFileSync("file3.txt");  // Waits
console.log("Done");

// Synchronous reads = everything waits
// If each file takes 1 second, total = 3 seconds
</code></pre>
<p><strong>Good (Non-Blocking):</strong></p>
<pre><code class="language-javascript">const fs = require("fs").promises;

async function loadFiles() {
  console.log("Start");
  
  const [file1, file2, file3] = await Promise.all([
    fs.readFile("file1.txt"),
    fs.readFile("file2.txt"),
    fs.readFile("file3.txt")
  ]);
  
  console.log("Done");
}

loadFiles();

// Asynchronous reads = runs in parallel
// If each file takes 1 second, total = ~1 second
// App stays responsive the whole time
</code></pre>
<p>Same files, but async is faster and doesn't freeze the app.</p>
<hr />
<h2>Problems With Blocking Code</h2>
<h3>1. Frozen User Interface</h3>
<p>Blocking code freezes the UI:</p>
<pre><code class="language-javascript">// Synchronous blocking code
function processLargeDataset() {
  let sum = 0;
  for (let i = 0; i &lt; 1000000000; i++) {
    sum += i;
  }
  return sum;
}

// User clicks, types, hovers = nothing happens
const result = processLargeDataset();
console.log("Result:", result);

// Finally, UI responds after computation
</code></pre>
<p>During <code>processLargeDataset()</code>, the browser can't respond to clicks or updates.</p>
<h3>2. Network Requests Block Everything</h3>
<pre><code class="language-javascript">// Hypothetical blocking network code
function fetchUserBlocking(userId) {
  const user = blockingFetch(`/api/users/${userId}`);
  return user;
}

// This waits forever if network is slow
const user = fetchUserBlocking(1);

// Nothing else runs until the user data arrives
</code></pre>
<p>If the network is slow, everything is stuck.</p>
<h3>3. Bad User Experience</h3>
<pre><code class="language-javascript">// Blocking code
console.log("Saving data...");
const result = blockingSaveToDatabase(data);  // Waits
console.log("Data saved");

// User sees "Saving" for a long time
// Can't do anything else
// Feels slow and broken
</code></pre>
<h3>4. Performance Issues</h3>
<pre><code class="language-javascript">// Blocking: Load 3 files one at a time
// File 1: 1 second
// File 2: 1 second
// File 3: 1 second
// Total: 3 seconds

// Non-blocking: Load 3 files in parallel
// File 1, 2, 3: 1 second each (at the same time)
// Total: ~1 second

// Same files, 3x faster with async
</code></pre>
<p>Blocking code is slow because operations can't overlap.</p>
<h3>5. No Responsiveness While Waiting</h3>
<pre><code class="language-javascript">// Blocking: App is stuck
while (waitingForData) {
  // Nothing
}

// Non-blocking: App keeps running
fetch(url).then(data =&gt; {
  // Handle when ready
});

// User can scroll, click, interact while waiting
</code></pre>
<hr />
<h2>The JavaScript Event Loop</h2>
<p>JavaScript handles async operations using an event loop:</p>
<pre><code class="language-plaintext">Call Stack (immediate code)
  |
  ├─ Execute synchronous code here
  └─ When done, check Task Queue

Task Queue (async callbacks)
  |
  ├─ setTimeout callbacks waiting
  ├─ Promise callbacks waiting
  ├─ Fetch callbacks waiting
  └─ When stack is empty, run next task

Event Loop
  |
  └─ Continuously checks: if stack empty and queue has tasks?
       └─ Move task from queue to stack
</code></pre>
<p>Example:</p>
<pre><code class="language-javascript">console.log("1");

setTimeout(() =&gt; {
  console.log("2");
}, 0);

console.log("3");

// Output:
// 1
// 3
// 2

// Why?
// 1. "1" runs immediately (stack)
// 2. setTimeout scheduled (goes to queue)
// 3. "3" runs immediately (stack)
// 4. Stack empty, event loop checks queue
// 5. "2" runs from queue
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Spot the blocking code:</strong></p>
<pre><code class="language-javascript">// Is this blocking or non-blocking?
const data = readFileSync("data.txt");

// Answer: Blocking. App freezes while reading.
</code></pre>
<p><strong>2. Convert blocking to non-blocking:</strong></p>
<pre><code class="language-javascript">// Blocking version
const file1 = readFileSync("file1.txt");
const file2 = readFileSync("file2.txt");

// Convert to async
</code></pre>
<p><strong>3. Understand the order:</strong></p>
<pre><code class="language-javascript">console.log("A");
setTimeout(() =&gt; console.log("B"), 0);
console.log("C");

// What order does it print? Why?
</code></pre>
<p><strong>4. Build a responsive app:</strong></p>
<pre><code class="language-javascript">// Fetch data but keep UI responsive
// Show loading state while fetching
// Update UI when data arrives
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Synchronous</strong> code runs line by line, each line waits for the previous.</p>
</li>
<li><p><strong>Asynchronous</strong> code starts operations but doesn't wait for them.</p>
</li>
<li><p>JavaScript uses the event loop to handle async operations.</p>
</li>
<li><p>Blocking code freezes the UI and makes apps feel slow.</p>
</li>
<li><p>Non-blocking code keeps the UI responsive.</p>
</li>
<li><p>Network requests, timers, and file operations should be async.</p>
</li>
<li><p>Synchronous file reads (<code>readFileSync</code>) block the entire app.</p>
</li>
<li><p>Asynchronous file reads keep everything responsive.</p>
</li>
<li><p><code>setTimeout</code>, <code>fetch</code>, and promises are async.</p>
</li>
<li><p><code>async/await</code> makes async code easier to read.</p>
</li>
<li><p>The task queue holds async callbacks until the call stack is empty.</p>
</li>
</ul>
<p>Master the difference between synchronous and asynchronous, and you'll write JavaScript that feels fast and responsive.</p>
<p>Happy coding! 🚀</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile.
🔗 Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Async/Await in JavaScript: Writing Cleaner Asynchronous Code
]]></title><description><![CDATA[Async/Await in JavaScript: Writing Cleaner Asynchronous Code
Promises fixed callback hell. But chaining many .then() calls still looks messy. Async/await lets you write asynchronous code that reads li]]></description><link>https://blog.harshx.in/async-await-in-javascript</link><guid isPermaLink="true">https://blog.harshx.in/async-await-in-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[js]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 10:34:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/cecfac0a-5907-45ad-8753-344ead981480.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Async/Await in JavaScript: Writing Cleaner Asynchronous Code</h1>
<p>Promises fixed callback hell. But chaining many <code>.then()</code> calls still looks messy. Async/await lets you write asynchronous code that reads like normal code.</p>
<p>If promises made async bearable, async/await made it obvious.</p>
<hr />
<h2>Why Async/Await Was Introduced</h2>
<p>Promises solved callback hell, but promise chains can be hard to follow.</p>
<h3>The Promise Chain Problem</h3>
<pre><code class="language-javascript">function fetchUserData(userId) {
  return fetch(`/api/users/${userId}`)
    .then(response =&gt; response.json())
    .then(user =&gt; {
      return fetch(`/api/posts/${user.id}`)
        .then(response =&gt; response.json())
        .then(posts =&gt; ({ user, posts }));
    });
}
</code></pre>
<p>It works, but reading it requires jumping between <code>.then()</code> blocks.</p>
<h3>The Async/Await Solution</h3>
<pre><code class="language-javascript">async function fetchUserData(userId) {
  const response = await fetch(`/api/users/${userId}`);
  const user = await response.json();
  
  const postsResponse = await fetch(`/api/posts/${user.id}`);
  const posts = await postsResponse.json();
  
  return { user, posts };
}
</code></pre>
<p>Same logic, reads top to bottom like normal code.</p>
<h3>Why It Matters</h3>
<ul>
<li>Easier to understand</li>
<li>Variables are in scope where you use them</li>
<li>Error handling with try/catch instead of <code>.catch()</code></li>
<li>Feels like synchronous code</li>
</ul>
<hr />
<h2>How Async Functions Work</h2>
<p>An <code>async</code> function automatically returns a promise.</p>
<h3>Basic Example</h3>
<pre><code class="language-javascript">async function myFunction() {
  return "Hello";
}

myFunction().then(result =&gt; console.log(result));
// Output: Hello
</code></pre>
<p>Even though you return a string, the function returns a promise.</p>
<h3>What Gets Returned</h3>
<pre><code class="language-javascript">async function getNumber() {
  return 42;
}

const result = getNumber();
console.log(result);  // Promise { &lt;pending&gt; }

result.then(num =&gt; console.log(num));  // 42
</code></pre>
<p>Every <code>async</code> function returns a promise.</p>
<h3>Two Ways to Call Async Functions</h3>
<p><strong>Option 1: With .then()</strong></p>
<pre><code class="language-javascript">async function getMessage() {
  return "Hello!";
}

getMessage().then(msg =&gt; console.log(msg));
</code></pre>
<p><strong>Option 2: With await (inside another async function)</strong></p>
<pre><code class="language-javascript">async function main() {
  const msg = await getMessage();
  console.log(msg);
}

main();
</code></pre>
<h3>Simple Async Example</h3>
<pre><code class="language-javascript">async function processData() {
  const response = await fetch("/api/data");
  const data = await response.json();
  const processed = data.map(item =&gt; item * 2);
  return processed;
}

processData().then(result =&gt; console.log(result));
</code></pre>
<p>Each <code>await</code> pauses until the promise resolves.</p>
<hr />
<h2>The Await Keyword</h2>
<p>The <code>await</code> keyword pauses execution until a promise resolves.</p>
<h3>Basic Example</h3>
<pre><code class="language-javascript">async function example() {
  console.log("Start");
  const result = await fetch("/api/data");
  console.log("End");
}

// Output:
// Start
// (waits for fetch)
// End
</code></pre>
<p>The function pauses at <code>await</code> and waits for the promise.</p>
<h3>Multiple Awaits</h3>
<pre><code class="language-javascript">async function loadUserPosts(userId) {
  const userResponse = await fetch(`/api/users/${userId}`);
  const user = await userResponse.json();
  
  const postsResponse = await fetch(`/api/posts/${user.id}`);
  const posts = await postsResponse.json();
  
  return { user, posts };
}
</code></pre>
<p>Each line waits for the previous one to finish.</p>
<h3>Await Only Works in Async Functions</h3>
<pre><code class="language-javascript">// Wrong: This doesn't work
function notAsync() {
  const data = await fetch("/api/data");  // SyntaxError
}

// Right: This works
async function isAsync() {
  const data = await fetch("/api/data");  // OK
}
</code></pre>
<p>You can only use <code>await</code> inside <code>async</code> functions.</p>
<h3>Parallel Operations With Promise.all()</h3>
<p>If operations don't depend on each other, run them together:</p>
<pre><code class="language-javascript">async function loadBoth() {
  const [user, posts] = await Promise.all([
    fetch("/api/users/1").then(r =&gt; r.json()),
    fetch("/api/posts/1").then(r =&gt; r.json())
  ]);
  
  return { user, posts };
}
</code></pre>
<p>This is faster than waiting for one, then the other.</p>
<hr />
<h2>Error Handling With Async Code</h2>
<p>Use <code>try/catch</code> blocks with async/await.</p>
<h3>Basic Try/Catch</h3>
<pre><code class="language-javascript">async function fetchUser(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`);
    const user = await response.json();
    return user;
  } catch (error) {
    console.log("Error:", error.message);
  }
}

fetchUser(1);
</code></pre>
<p>If any <code>await</code> fails, <code>catch</code> handles it.</p>
<h3>Error Object Details</h3>
<pre><code class="language-javascript">async function operation() {
  try {
    const result = await riskyFunction();
    console.log("Success:", result);
  } catch (error) {
    console.log("Message:", error.message);
    console.log("Type:", error.name);
    console.log("Stack:", error.stack);
  }
}
</code></pre>
<p>The error object has all the details.</p>
<h3>Finally Block</h3>
<pre><code class="language-javascript">async function processFile(filename) {
  let file;
  
  try {
    file = await openFile(filename);
    const content = await file.read();
    console.log("Content:", content);
  } catch (error) {
    console.log("Error:", error.message);
  } finally {
    if (file) {
      await file.close();  // Always close
    }
  }
}
</code></pre>
<p>The <code>finally</code> block always runs.</p>
<h3>Handle Different Errors</h3>
<pre><code class="language-javascript">async function complexOp() {
  try {
    const user = await getUser();
    const posts = await getPosts(user.id);
    return { user, posts };
  } catch (error) {
    if (error.message.includes("User not found")) {
      console.log("No user");
    } else if (error.message.includes("Network")) {
      console.log("Network problem");
    } else {
      console.log("Other error:", error);
    }
  }
}
</code></pre>
<hr />
<h2>Promise vs Async/Await</h2>
<p>Both work the same way. Async/await is just cleaner syntax.</p>
<h3>Side-by-Side Comparison</h3>
<p><strong>With Promises:</strong></p>
<pre><code class="language-javascript">function getUser(userId) {
  return fetch(`/api/users/${userId}`)
    .then(response =&gt; response.json())
    .then(user =&gt; {
      console.log("User:", user);
      return user;
    })
    .catch(error =&gt; console.log("Error:", error));
}
</code></pre>
<p><strong>With Async/Await:</strong></p>
<pre><code class="language-javascript">async function getUser(userId) {
  try {
    const response = await fetch(`/api/users/${userId}`);
    const user = await response.json();
    console.log("User:", user);
    return user;
  } catch (error) {
    console.log("Error:", error);
  }
}
</code></pre>
<p>Async/await reads more naturally.</p>
<h3>Readability Difference</h3>
<p><strong>Promises:</strong></p>
<pre><code class="language-plaintext">.then(...)
.then(...)
.then(...)
.catch(...)

Requires jumping between blocks
</code></pre>
<p><strong>Async/Await:</strong></p>
<pre><code class="language-plaintext">await operation1
await operation2
await operation3
try/catch

Reads top to bottom
</code></pre>
<h3>They're Compatible</h3>
<p>You can use <code>.then()</code> with async/await:</p>
<pre><code class="language-javascript">async function loadData() {
  const response = await fetch("/api/data");
  return response.json();
}

// Still use .then()
loadData().then(data =&gt; console.log(data));

// Or await it
const data = await loadData();
</code></pre>
<p>Async/await doesn't replace promises. It's built on them.</p>
<hr />
<h2>Converting Promises to Async/Await</h2>
<h3>Example: Fetch Multiple Resources</h3>
<p><strong>Promise Version:</strong></p>
<pre><code class="language-javascript">function loadUserWithPosts(userId) {
  let userData;
  
  return fetch(`/api/users/${userId}`)
    .then(response =&gt; response.json())
    .then(user =&gt; {
      userData = user;
      return fetch(`/api/posts/${user.id}`);
    })
    .then(response =&gt; response.json())
    .then(posts =&gt; {
      return { user: userData, posts };
    })
    .catch(error =&gt; {
      console.log("Error:", error);
      return null;
    });
}
</code></pre>
<p><strong>Async/Await Version:</strong></p>
<pre><code class="language-javascript">async function loadUserWithPosts(userId) {
  try {
    const userResponse = await fetch(`/api/users/${userId}`);
    const user = await userResponse.json();
    
    const postsResponse = await fetch(`/api/posts/${user.id}`);
    const posts = await postsResponse.json();
    
    return { user, posts };
  } catch (error) {
    console.log("Error:", error);
    return null;
  }
}
</code></pre>
<p>Much clearer. No temporary variables or nested callbacks.</p>
<hr />
<h2>Async Function Execution Flow</h2>
<pre><code class="language-plaintext">START
  |
  v
Enter async function
  |
  v
Execute line by line
  |
  ├─ await expression → pause
  |     |
  |     └─ wait for promise
  |           |
  |           └─ resolve
  |
  ├─ Continue
  |
  └─ await expression → pause
        |
        └─ wait for promise
              |
              └─ resolve
  |
  v
Return value (wrapped in promise)
  |
  v
END
</code></pre>
<p>Each <code>await</code> pauses execution. When the promise resolves, execution continues.</p>
<hr />
<h2>Real-World Example: API Call with Data Processing</h2>
<pre><code class="language-javascript">async function fetchAndProcessUserData(userId) {
  try {
    // Fetch user
    console.log(`Fetching user ${userId}...`);
    const userResponse = await fetch(`/api/users/${userId}`);
    
    if (!userResponse.ok) {
      throw new Error(`HTTP error! status: ${userResponse.status}`);
    }
    
    const user = await userResponse.json();
    
    // Fetch posts
    console.log(`Fetching posts for ${user.name}...`);
    const postsResponse = await fetch(`/api/posts?userId=${user.id}`);
    const posts = await postsResponse.json();
    
    // Process data
    const result = {
      user: user.name,
      email: user.email,
      postCount: posts.length,
      recentPost: posts[0]?.title
    };
    
    console.log("Processing complete");
    return result;
    
  } catch (error) {
    console.error("Failed to fetch data:", error.message);
    return null;
    
  } finally {
    console.log("Operation finished");
  }
}

// Call it
fetchAndProcessUserData(1)
  .then(result =&gt; console.log("Result:", result))
  .catch(err =&gt; console.log("Outer error:", err));
</code></pre>
<p>Clean, readable, and easy to follow.</p>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Convert a promise chain to async/await:</strong></p>
<pre><code class="language-javascript">// Promise version
function getDataAndProcess() {
  return fetch("/api/data")
    .then(r =&gt; r.json())
    .then(data =&gt; processData(data))
    .catch(err =&gt; console.log(err));
}

// Convert to async/await
</code></pre>
<p><strong>2. Handle errors with try/catch:</strong></p>
<pre><code class="language-javascript">async function fetchMultiple() {
  // Fetch from /api/users and /api/posts
  // Handle any errors that occur
  // Log success and errors
}
</code></pre>
<p><strong>3. Use parallel requests:</strong></p>
<pre><code class="language-javascript">async function loadDashboard() {
  // Fetch users, posts, and comments at the same time
  // Use Promise.all() for parallel requests
  // Return all data combined
}
</code></pre>
<p><strong>4. Chain dependent operations:</strong></p>
<pre><code class="language-javascript">async function getUserPostComments(userId) {
  // Get user
  // Get user's posts
  // Get comments on first post
  // Return everything together
}
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p>Async/await is syntactic sugar for promises.</p>
</li>
<li><p><code>async</code> functions always return a promise.</p>
</li>
<li><p><code>await</code> pauses execution until a promise resolves.</p>
</li>
<li><p><code>await</code> only works inside <code>async</code> functions.</p>
</li>
<li><p>Use <code>try/catch</code> for error handling.</p>
</li>
<li><p><code>finally</code> block always runs.</p>
</li>
<li><p>Async/await is easier to read than promise chains.</p>
</li>
<li><p>Use <code>Promise.all()</code> to run operations in parallel.</p>
</li>
<li><p>Variables are in scope where you use them.</p>
</li>
<li><p><code>.then()</code> and async/await can be mixed.</p>
</li>
<li><p>Async/await code reads like synchronous code.</p>
</li>
</ul>
<p>Async/await makes promises easier to work with. Learn both and you'll truly understand JavaScript's async model.</p>
<p>Happy coding! 🚀</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile.
🔗 Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Error Handling in JavaScript: Try, Catch, Finally
]]></title><description><![CDATA[Error Handling in JavaScript: Try, Catch, Finally
Code breaks. Users do unexpected things. Networks fail. Without error handling, your app crashes. With it, you handle problems gracefully and stay in ]]></description><link>https://blog.harshx.in/error-handling-in-javascript</link><guid isPermaLink="true">https://blog.harshx.in/error-handling-in-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[js]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 10:32:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/44cec71f-08bf-40b2-815f-67e57a458799.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1>Error Handling in JavaScript: Try, Catch, Finally</h1>
<p>Code breaks. Users do unexpected things. Networks fail. Without error handling, your app crashes. With it, you handle problems gracefully and stay in control.</p>
<p>Error handling isn't about preventing all mistakes. It's about deciding what to do when they happen.</p>
<hr />
<h2>What Errors Are in JavaScript</h2>
<p>An error is when something goes wrong while code runs. JavaScript throws an error and stops.</p>
<h3>Common Error Types</h3>
<p><strong>Reference Error — Using a variable that doesn't exist:</strong></p>
<pre><code class="language-javascript">console.log(someVariable);
// ReferenceError: someVariable is not defined
</code></pre>
<p><strong>Type Error — Calling a method on the wrong type:</strong></p>
<pre><code class="language-javascript">let number = 42;
number.toUpperCase();
// TypeError: number.toUpperCase is not a function
</code></pre>
<p><strong>Range Error — Value outside acceptable range:</strong></p>
<pre><code class="language-javascript">new Array(-1);
// RangeError: Invalid array length
</code></pre>
<h3>Without Error Handling</h3>
<pre><code class="language-javascript">function loadFile(filename) {
  const data = JSON.parse(fs.readFileSync(filename, "utf8"));
  return data;
}

loadFile("missing.json");
// Error: file not found
// App crashes. User sees nothing.
</code></pre>
<h3>With Error Handling</h3>
<pre><code class="language-javascript">function loadFile(filename) {
  try {
    const data = JSON.parse(fs.readFileSync(filename, "utf8"));
    return data;
  } catch (error) {
    return { default: true };
  }
}

loadFile("missing.json");
// Returns: { default: true }
// App keeps running.
</code></pre>
<hr />
<h2>Using Try and Catch Blocks</h2>
<p>The <code>try</code> block has code that might fail. The <code>catch</code> block handles it if it does.</p>
<h3>Basic Structure</h3>
<pre><code class="language-javascript">try {
  // Code that might throw an error
  riskyOperation();
} catch (error) {
  // Handle the error
  console.log("Something went wrong:", error.message);
}
</code></pre>
<h3>Real Example: Parsing JSON</h3>
<pre><code class="language-javascript">let jsonString = '{ "name": "Alice" }';

try {
  let data = JSON.parse(jsonString);
  console.log("Parsed successfully:", data);
} catch (error) {
  console.log("Invalid JSON:", error.message);
}
</code></pre>
<p>If it's valid JSON, it parses. If not, <code>catch</code> handles it.</p>
<h3>With Broken JSON</h3>
<pre><code class="language-javascript">let jsonString = '{ "name": "Alice"';  // Missing closing brace

try {
  let data = JSON.parse(jsonString);
  console.log("Parsed:", data);
} catch (error) {
  console.log("Invalid JSON:", error.message);
  // Output: Invalid JSON: Unexpected end of JSON input
}
</code></pre>
<p>The error happens in <code>try</code>. Instead of crashing, <code>catch</code> handles it.</p>
<h3>The Error Object</h3>
<p>The error object has useful properties:</p>
<pre><code class="language-javascript">try {
  nonexistentFunction();
} catch (error) {
  console.log(error.message);  // The message
  console.log(error.name);     // Error type
  console.log(error.stack);    // Full trace
}
</code></pre>
<h3>Multiple Operations</h3>
<pre><code class="language-javascript">try {
  const data = fs.readFileSync("data.json", "utf8");
  const parsed = JSON.parse(data);
  processData(parsed);
} catch (error) {
  console.log("Error:", error.message);
}
</code></pre>
<p>If any operation fails, <code>catch</code> handles it.</p>
<hr />
<h2>The Finally Block</h2>
<p>The <code>finally</code> block always runs, no matter what. Success or failure, it executes.</p>
<h3>Structure</h3>
<pre><code class="language-javascript">try {
  // Code that might fail
} catch (error) {
  // Handle the error
} finally {
  // Always runs
}
</code></pre>
<h3>Real Example: Close a Database</h3>
<pre><code class="language-javascript">const db = openDatabase("app.db");

try {
  const user = db.query("SELECT * FROM users WHERE id = 1");
  console.log("User found:", user);
} catch (error) {
  console.log("Query failed:", error.message);
} finally {
  db.close();  // Always close, success or failure
}
</code></pre>
<p>The database closes whether the query works or fails.</p>
<h3>Execution Order</h3>
<pre><code class="language-plaintext">try block runs
  |
  ├─ Success → skip catch → go to finally
  └─ Failure → catch runs → then finally

finally always runs last
</code></pre>
<h3>Resource Cleanup</h3>
<pre><code class="language-javascript">function processFile(filename) {
  let file;
  
  try {
    file = openFile(filename);
    const content = file.read();
    console.log("File processed");
  } catch (error) {
    console.log("Error:", error.message);
  } finally {
    if (file) {
      file.close();  // Clean up
    }
  }
}
</code></pre>
<p>The file closes whether processing succeeds or fails.</p>
<hr />
<h2>Try → Catch → Finally Execution Flow</h2>
<pre><code class="language-plaintext">START
  |
  v
TRY BLOCK
  |
  ├─── No error
  |      |
  |      v
  |    Code runs successfully
  |      |
  |      v
  |    SKIP catch block
  |      |
  └──────┤
  |      |
  ├─── Error occurs
  |      |
  |      v
  |    Jump to CATCH block
  |      |
  |      v
  |    Handle error
  |      |
  └──────┤
  |      |
  v      v
FINALLY BLOCK (always runs)
  |
  v
END
</code></pre>
<hr />
<h2>Throwing Custom Errors</h2>
<p>When something is wrong with your logic, create your own error.</p>
<h3>Throw Statement</h3>
<pre><code class="language-javascript">function validateAge(age) {
  if (age &lt; 0) {
    throw new Error("Age cannot be negative");
  }
  return age;
}

try {
  validateAge(-5);
} catch (error) {
  console.log("Validation failed:", error.message);
  // Output: Validation failed: Age cannot be negative
}
</code></pre>
<h3>Error Types You Can Throw</h3>
<pre><code class="language-javascript">throw new Error("Something went wrong");
throw new TypeError("Expected a number");
throw new RangeError("Value out of range");
throw "Quick error message";
</code></pre>
<h3>Custom Error Classes</h3>
<pre><code class="language-javascript">class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = "ValidationError";
  }
}

function validateEmail(email) {
  if (!email.includes("@")) {
    throw new ValidationError("Invalid email");
  }
  return email;
}

try {
  validateEmail("notanemail");
} catch (error) {
  if (error instanceof ValidationError) {
    console.log("Email error:", error.message);
  }
}
</code></pre>
<h3>When to Throw</h3>
<pre><code class="language-javascript">function divideNumbers(a, b) {
  if (typeof a !== "number" || typeof b !== "number") {
    throw new TypeError("Both must be numbers");
  }
  
  if (b === 0) {
    throw new Error("Cannot divide by zero");
  }
  
  return a / b;
}

try {
  divideNumbers(10, 2);   // Works: 5
  divideNumbers(10, 0);   // Throws error
} catch (error) {
  console.log("Math error:", error.message);
}
</code></pre>
<hr />
<h2>Why Error Handling Matters</h2>
<h3>1. Graceful Failure</h3>
<p>Without error handling, your app crashes:</p>
<pre><code class="language-javascript">// Crashes if database fails
app.get("/user/:id", (req, res) =&gt; {
  const user = db.findUser(req.params.id);
  res.json(user);
});

// Handles the error gracefully
app.get("/user/:id", (req, res) =&gt; {
  try {
    const user = db.findUser(req.params.id);
    res.json(user);
  } catch (error) {
    res.status(500).json({ error: "User not found" });
  }
});
</code></pre>
<p>User gets a message instead of a blank screen.</p>
<h3>2. Better Debugging</h3>
<p>Error objects show you where the problem is:</p>
<pre><code class="language-javascript">try {
  riskyFunction();
} catch (error) {
  console.log(error.stack);
  // Shows file, line number, and function names
  // Helps you find bugs fast
}
</code></pre>
<h3>3. Resource Cleanup</h3>
<p>With <code>finally</code>, resources always get cleaned up:</p>
<pre><code class="language-javascript">let connection;

try {
  connection = openConnection();
} catch (error) {
  console.log("Error:", error.message);
} finally {
  if (connection) {
    connection.close();  // Don't leak resources
  }
}
</code></pre>
<p>Without <code>finally</code>, connections stay open if an error happens.</p>
<h3>4. Better User Experience</h3>
<p>Handle errors cleanly:</p>
<pre><code class="language-javascript">function saveData(data) {
  try {
    validateData(data);
    db.save(data);
    return { success: true };
  } catch (error) {
    return { 
      success: false, 
      message: "Could not save. Please try again." 
    };
  }
}
</code></pre>
<p>Users see a clear message, not a crash.</p>
<hr />
<h2>Real-World Example: Parsing User Input</h2>
<pre><code class="language-javascript">function processUserInput(jsonString) {
  try {
    // Parse the JSON
    const data = JSON.parse(jsonString);
    
    // Validate the data
    if (!data.name || !data.email) {
      throw new Error("Missing required fields");
    }
    
    // Process the data
    const result = {
      name: data.name.trim(),
      email: data.email.toLowerCase()
    };
    
    console.log("Processing successful:", result);
    return result;
    
  } catch (error) {
    if (error instanceof SyntaxError) {
      console.log("Invalid JSON format:", error.message);
    } else if (error.message.includes("required")) {
      console.log("Validation error:", error.message);
    } else {
      console.log("Unexpected error:", error.message);
    }
    
    return null;
    
  } finally {
    console.log("Processing complete");
  }
}

// Test it
processUserInput('{ "name": "Alice", "email": "alice@example.com" }');
// Output: Processing successful: { name: 'Alice', email: 'alice@example.com' }
//         Processing complete

processUserInput('invalid json');
// Output: Invalid JSON format: Unexpected token i...
//         Processing complete

processUserInput('{ "name": "Bob" }');
// Output: Validation error: Missing required fields
//         Processing complete
</code></pre>
<p>Each scenario is handled appropriately.</p>
<hr />
<h2>Error Handling Patterns</h2>
<h3>Pattern 1: Try-Catch-Finally</h3>
<pre><code class="language-javascript">try {
  // Do something
} catch (error) {
  // Handle error
} finally {
  // Cleanup
}
</code></pre>
<h3>Pattern 2: Catch and Rethrow</h3>
<pre><code class="language-javascript">try {
  database.query("SELECT * FROM users");
} catch (error) {
  console.log("Database error:", error);
  throw error;  // Pass it up to the caller
}
</code></pre>
<h3>Pattern 3: Catch and Return Default</h3>
<pre><code class="language-javascript">function getConfig() {
  try {
    return loadConfig();
  } catch (error) {
    return defaultConfig;  // Use defaults if load fails
  }
}
</code></pre>
<h3>Pattern 4: Catch Specific Errors</h3>
<pre><code class="language-javascript">try {
  operation();
} catch (error) {
  if (error instanceof TypeError) {
    console.log("Type error:", error.message);
  } else if (error instanceof RangeError) {
    console.log("Range error:", error.message);
  } else {
    console.log("Unknown error:", error.message);
  }
}
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Parse JSON safely:</strong></p>
<pre><code class="language-javascript">const jsonString = '{ "name": "Alice", "age": 25 }';

// Write a function that parses the JSON
// If parsing fails, return a default object
</code></pre>
<p><strong>2. Handle multiple errors:</strong></p>
<pre><code class="language-javascript">function divideAndLog(a, b) {
  try {
    // Check if both are numbers
    // Check if b is not zero
    // Divide and log result
  } catch (error) {
    // Handle the error
  }
}
</code></pre>
<p><strong>3. Create a custom error:</strong></p>
<pre><code class="language-javascript">// Create a PasswordError class
// Throw it if password is too short
// Catch it and show a message
</code></pre>
<p><strong>4. Use finally for cleanup:</strong></p>
<pre><code class="language-javascript">let file = null;

try {
  file = openFile("data.txt");
  // Read and process the file
} catch (error) {
  // Handle error
} finally {
  // Make sure file closes
}
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Errors</strong> happen when code breaks. JavaScript throws and stops.</p>
</li>
<li><p><strong>Try block</strong> contains code that might fail.</p>
</li>
<li><p><strong>Catch block</strong> handles errors if they happen.</p>
</li>
<li><p><strong>Finally block</strong> always runs, success or failure.</p>
</li>
<li><p><strong>Throw</strong> keyword creates your own errors.</p>
</li>
<li><p>Error objects have <code>.message</code>, <code>.stack</code>, and <code>.name</code>.</p>
</li>
<li><p>Error handling lets you fail gracefully instead of crashing.</p>
</li>
<li><p>Use <code>finally</code> to clean up resources.</p>
</li>
<li><p>Catch specific error types for different handling.</p>
</li>
<li><p>Error messages help you debug faster.</p>
</li>
<li><p>Good error handling improves user experience.</p>
</li>
</ul>
<p>Error handling isn't optional. It's how you control what happens when things go wrong.</p>
<p>Happy coding! 🚀</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile.
🔗 Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Spread vs Rest Operators in JavaScript
]]></title><description><![CDATA[The spread and rest operators look identical: three dots (...). But they do opposite things. One expands values. One collects them. Understand the difference and you'll write cleaner, more powerful co]]></description><link>https://blog.harshx.in/spread-vs-rest-operators-in-javascript</link><guid isPermaLink="true">https://blog.harshx.in/spread-vs-rest-operators-in-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 10:29:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/08738fff-c22b-4ae1-90db-c6a1e3ea5664.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The spread and rest operators look identical: three dots (<code>...</code>). But they do opposite things. One expands values. One collects them. Understand the difference and you'll write cleaner, more powerful code.</p>
<p>This is about what spread and rest do, how they differ, and when to use each one.</p>
<hr />
<h2>Understanding the Three Dots</h2>
<p>The <code>...</code> syntax appears in two different contexts:</p>
<pre><code class="language-plaintext">Spread:  Takes many elements and spreads them out
Rest:    Takes many values and collects them together
</code></pre>
<p>The syntax is the same. The context is different. That's what matters.</p>
<hr />
<h2>What the Spread Operator Does</h2>
<p>The spread operator takes an iterable (array, string, or object) and expands it in-place.</p>
<h3>Expanding an Array</h3>
<pre><code class="language-javascript">const arr = [1, 2, 3];

console.log(arr);        // [1, 2, 3]
console.log(...arr);     // 1 2 3
</code></pre>
<p>Without spread: The array is printed as an array.</p>
<p>With spread: The elements are printed individually.</p>
<h3>Spread Unpacks Values</h3>
<pre><code class="language-plaintext">Without spread:  [1, 2, 3]
                 One array

With spread:     1, 2, 3
                 Three separate values
</code></pre>
<h3>Real Example: Function Arguments</h3>
<pre><code class="language-javascript">function add(a, b, c) {
  return a + b + c;
}

const numbers = [1, 2, 3];

// Without spread
add(numbers[0], numbers[1], numbers[2]);  // 6 (clunky)

// With spread
add(...numbers);  // 6 (clean)
</code></pre>
<p>Spread takes <code>[1, 2, 3]</code> and expands it to <code>1, 2, 3</code>. Then those values are passed as separate arguments.</p>
<h3>Spread with Math Functions</h3>
<pre><code class="language-javascript">const numbers = [5, 6, 2, 8, 1];

// Find max without spread
Math.max(numbers[0], numbers[1], numbers[2], numbers[3], numbers[4]); // 8

// With spread
Math.max(...numbers); // 8
</code></pre>
<p><code>Math.max()</code> expects individual arguments, not an array. Spread converts the array to individual arguments.</p>
<h3>Spreading Strings</h3>
<p>Strings are iterable. You can spread them:</p>
<pre><code class="language-javascript">const str = "hello";

console.log(...str);  // h e l l o

const arr = [...str];
console.log(arr);     // ["h", "e", "l", "l", "o"]
</code></pre>
<p>Spread expands the string into individual characters.</p>
<hr />
<h2>What the Rest Operator Does</h2>
<p>The rest operator collects multiple values into a single array.</p>
<h3>Collecting Function Arguments</h3>
<pre><code class="language-javascript">function sum(...numbers) {
  console.log(numbers);  // An array of all arguments
  let total = 0;
  for (let num of numbers) {
    total += num;
  }
  return total;
}

sum(1, 2, 3);        // numbers = [1, 2, 3]
sum(1, 2, 3, 4, 5);  // numbers = [1, 2, 3, 4, 5]
</code></pre>
<p>Rest collects all arguments into a single array <code>numbers</code>.</p>
<h3>Rest Collects Values</h3>
<pre><code class="language-plaintext">Without rest:  function (a, b, c) { }
               Can only accept 3 arguments

With rest:     function (...args) { }
               Can accept any number of arguments
</code></pre>
<h3>Rest with Regular Parameters</h3>
<pre><code class="language-javascript">function greet(greeting, ...names) {
  console.log(greeting);  // Single value
  console.log(names);     // Array of remaining values
}

greet("Hello", "Alice", "Bob", "Charlie");

// Output:
// "Hello"
// ["Alice", "Bob", "Charlie"]
</code></pre>
<p>The first argument goes to <code>greeting</code>. The rest go into the <code>names</code> array.</p>
<h3>Rest in Array Destructuring</h3>
<pre><code class="language-javascript">const arr = [1, 2, 3, 4, 5];

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

console.log(first);   // 1
console.log(second);  // 2
console.log(rest);    // [3, 4, 5]
</code></pre>
<p>The first two elements are assigned individually. The rest are collected into an array.</p>
<h3>Rest in Object Destructuring</h3>
<pre><code class="language-javascript">const person = {
  name: "John",
  age: 30,
  city: "New York",
  country: "USA"
};

const { name, age, ...location } = person;

console.log(name);      // "John"
console.log(age);       // 30
console.log(location);  // { city: "New York", country: "USA" }
</code></pre>
<p>Named properties are extracted. The rest are collected into a new object.</p>
<hr />
<h2>Spread vs Rest: Key Differences</h2>
<h3>Context Matters</h3>
<table>
<thead>
<tr>
<th>Usage</th>
<th>Operator</th>
<th>Name</th>
<th>Does</th>
</tr>
</thead>
<tbody><tr>
<td>Function call</td>
<td><code>...arr</code></td>
<td>Spread</td>
<td>Expands array to arguments</td>
</tr>
<tr>
<td>Array literal</td>
<td><code>[...arr]</code></td>
<td>Spread</td>
<td>Expands array into new array</td>
</tr>
<tr>
<td>Function parameter</td>
<td><code>(...args)</code></td>
<td>Rest</td>
<td>Collects arguments into array</td>
</tr>
<tr>
<td>Destructuring</td>
<td><code>[a, ...rest]</code></td>
<td>Rest</td>
<td>Collects remaining into array</td>
</tr>
</tbody></table>
<h3>Visual Comparison</h3>
<pre><code class="language-plaintext">SPREAD (Unpacking)
[1, 2, 3]
   ↓
1, 2, 3

REST (Collecting)
1, 2, 3
   ↓
[1, 2, 3]
</code></pre>
<p>Spread goes outward. Rest goes inward.</p>
<h3>Position Matters</h3>
<p><strong>Spread can appear anywhere in an expression:</strong></p>
<pre><code class="language-javascript">const a = [1, 2];
const b = [3, 4];

const combined = [0, ...a, ...b, 5];
console.log(combined);  // [0, 1, 2, 3, 4, 5]
</code></pre>
<p><strong>Rest can only be the last parameter:</strong></p>
<pre><code class="language-javascript">function test(...rest, param) { }  // ERROR
function test(param, ...rest) { }  // CORRECT
</code></pre>
<p>Rest must come last because it collects everything remaining.</p>
<hr />
<h2>Using Spread with Arrays</h2>
<h3>Copy an Array</h3>
<pre><code class="language-javascript">const original = [1, 2, 3];

// Shallow copy
const copy = [...original];

console.log(copy);           // [1, 2, 3]
console.log(copy === original); // false (different arrays)
</code></pre>
<p>Spread creates a new array with the same elements.</p>
<h3>Combine Arrays</h3>
<pre><code class="language-javascript">const arr1 = [1, 2];
const arr2 = [3, 4];

const combined = [...arr1, ...arr2];
console.log(combined);  // [1, 2, 3, 4]
</code></pre>
<p>Spread expands both arrays into a new one.</p>
<h3>Insert Elements</h3>
<pre><code class="language-javascript">const arr = [1, 2, 5];

// Insert 3 and 4 between 2 and 5
const result = [1, 2, 3, 4, 5];

// Or do it with spread
const start = [1, 2];
const end = [5];
const final = [...start, 3, 4, ...end];
console.log(final);  // [1, 2, 3, 4, 5]
</code></pre>
<h3>Remove Duplicates</h3>
<pre><code class="language-javascript">const arr = [1, 2, 2, 3, 3, 3, 4];

// Using Set (removes duplicates)
const unique = [...new Set(arr)];
console.log(unique);  // [1, 2, 3, 4]
</code></pre>
<p>Spread converts the Set back to an array.</p>
<h3>Reverse an Array</h3>
<pre><code class="language-javascript">const arr = [1, 2, 3];

// Using spread with reverse
const reversed = [...arr].reverse();
console.log(arr);        // [1, 2, 3] (original unchanged)
console.log(reversed);   // [3, 2, 1] (new reversed array)
</code></pre>
<p>Spread creates a copy first, so the original isn't modified.</p>
<hr />
<h2>Using Spread with Objects</h2>
<h3>Copy an Object</h3>
<pre><code class="language-javascript">const original = { name: "John", age: 30 };

// Shallow copy
const copy = { ...original };

console.log(copy);              // { name: "John", age: 30 }
console.log(copy === original); // false (different objects)
</code></pre>
<p>Spread creates a new object with the same properties.</p>
<h3>Merge Objects</h3>
<pre><code class="language-javascript">const obj1 = { name: "John", age: 30 };
const obj2 = { city: "New York", country: "USA" };

const merged = { ...obj1, ...obj2 };
console.log(merged);
// { name: "John", age: 30, city: "New York", country: "USA" }
</code></pre>
<p>Spread expands both objects into one.</p>
<h3>Override Properties</h3>
<pre><code class="language-javascript">const defaults = { theme: "light", language: "en" };
const userSettings = { theme: "dark" };

const settings = { ...defaults, ...userSettings };
console.log(settings);
// { theme: "dark", language: "en" }
</code></pre>
<p>Properties from <code>userSettings</code> override defaults because they come later.</p>
<h3>Add New Properties</h3>
<pre><code class="language-javascript">const user = { name: "John", age: 30 };

const updated = {
  ...user,
  age: 31,
  email: "john@example.com"
};

console.log(updated);
// { name: "John", age: 31, email: "john@example.com" }
</code></pre>
<p>Spread the original, then add or override properties.</p>
<h3>Exclude Properties</h3>
<pre><code class="language-javascript">const user = { name: "John", age: 30, password: "secret" };

// Remove password
const { password, ...publicUser } = user;

console.log(publicUser);
// { name: "John", age: 30 }
</code></pre>
<p>Rest collects everything except the excluded property.</p>
<hr />
<h2>Practical Use Cases</h2>
<h3>Use Case 1: Flexible Function Arguments</h3>
<pre><code class="language-javascript">// Without rest - limited to exact arguments
function oldSum(a, b, c) {
  return a + b + c;
}

oldSum(1, 2, 3);       // 6
oldSum(1, 2, 3, 4);    // 10 (4 ignored)

// With rest - any number of arguments
function newSum(...numbers) {
  return numbers.reduce((sum, n) =&gt; sum + n, 0);
}

newSum(1, 2, 3);       // 6
newSum(1, 2, 3, 4);    // 10
newSum(1, 2, 3, 4, 5); // 15
</code></pre>
<h3>Use Case 2: Cloning Data</h3>
<pre><code class="language-javascript">const original = { id: 1, name: "Product", price: 99.99 };

// Create a copy to modify
const edited = { ...original, price: 79.99 };

console.log(original); // { id: 1, name: "Product", price: 99.99 }
console.log(edited);   // { id: 1, name: "Product", price: 79.99 }
</code></pre>
<p>The original remains unchanged.</p>
<h3>Use Case 3: Passing Arguments</h3>
<pre><code class="language-javascript">function greet(greeting, name, punctuation) {
  return greeting + " " + name + punctuation;
}

const args = ["Hello", "Alice", "!"];

// Without spread
greet(args[0], args[1], args[2]);  // "Hello Alice!"

// With spread
greet(...args);  // "Hello Alice!"
</code></pre>
<p>Spread converts the array to function arguments.</p>
<h3>Use Case 4: State Management (React-style)</h3>
<pre><code class="language-javascript">// Update a single property in state
const state = { user: "John", count: 5, loading: false };

const newState = {
  ...state,
  count: state.count + 1
};

console.log(state);    // { user: "John", count: 5, loading: false }
console.log(newState); // { user: "John", count: 6, loading: false }
</code></pre>
<p>Create a new object with one property changed.</p>
<h3>Use Case 5: API Response Handling</h3>
<pre><code class="language-javascript">const apiResponse = {
  status: 200,
  data: { id: 1, name: "John" },
  timestamp: "2026-05-04"
};

// Extract just the data
const { status, timestamp, ...userData } = apiResponse;

console.log(userData);  // { id: 1, name: "John" }
</code></pre>
<p>Rest extracts the important data.</p>
<h3>Use Case 6: Building Arrays Dynamically</h3>
<pre><code class="language-javascript">const baseItems = ["apple", "banana"];
const newItems = ["orange"];
const userItems = ["grape"];

const groceryList = [
  "store items:",
  ...baseItems,
  ...newItems,
  ...userItems
];

console.log(groceryList);
// ["store items:", "apple", "banana", "orange", "grape"]
</code></pre>
<p>Spread combines multiple arrays cleanly.</p>
<h3>Use Case 7: Default Parameters with Objects</h3>
<pre><code class="language-javascript">const defaultConfig = {
  timeout: 5000,
  retries: 3,
  verbose: false
};

function makeRequest(url, config = {}) {
  const finalConfig = { ...defaultConfig, ...config };
  return finalConfig;
}

makeRequest("https://api.example.com");
// { timeout: 5000, retries: 3, verbose: false }

makeRequest("https://api.example.com", { timeout: 10000 });
// { timeout: 10000, retries: 3, verbose: false }
</code></pre>
<p>Merge user config with defaults.</p>
<h3>Use Case 8: Filtering with Rest</h3>
<pre><code class="language-javascript">const numbers = [1, 2, 3, 4, 5];

const [first, ...rest] = numbers;
const even = rest.filter(n =&gt; n % 2 === 0);

console.log(even);  // [2, 4]
</code></pre>
<p>Extract and process remaining elements.</p>
<hr />
<h2>Spread and Rest Diagrams</h2>
<h3>Spread: Expanding Elements</h3>
<pre><code class="language-plaintext">Array: [1, 2, 3]
    ↓
Spread: ...arr
    ↓
Expanded: 1, 2, 3
    ↓
Used in: Function calls, array literals, object literals
</code></pre>
<h3>Rest: Collecting Values</h3>
<pre><code class="language-plaintext">Values: 1, 2, 3, 4, 5
    ↓
Rest: ...rest
    ↓
Collected: [1, 2, 3, 4, 5]
    ↓
Stored in: Array parameter, destructuring
</code></pre>
<h3>Visual Comparison</h3>
<pre><code class="language-plaintext">SPREAD (Unpacking)
        [1, 2, 3]
              ↓
        1 , 2 , 3
              ↓
    Pass to function / merge

REST (Collecting)
        1 , 2 , 3
              ↓
        [1, 2, 3]
              ↓
    Store in variable
</code></pre>
<hr />
<h2>Advanced Examples</h2>
<h3>Combining Spread and Rest</h3>
<pre><code class="language-javascript">const arr = [1, 2, 3, 4, 5];

// Destructure with rest
const [first, second, ...remaining] = arr;

// Spread to reconstruct
const reconstructed = [first, second, ...remaining];

console.log(reconstructed);  // [1, 2, 3, 4, 5]
</code></pre>
<h3>Deep Object Merging (Single Level)</h3>
<pre><code class="language-javascript">const user = { name: "John", address: { city: "NY" } };
const update = { address: { zip: "10001" } };

// Shallow merge - overwrites entire address
const result = { ...user, ...update };
console.log(result);
// { name: "John", address: { zip: "10001" } }
// Note: city is lost!

// For deep merge, handle nested objects
const deepResult = {
  ...user,
  address: { ...user.address, ...update.address }
};
console.log(deepResult);
// { name: "John", address: { city: "NY", zip: "10001" } }
</code></pre>
<h3>Rest with Named Parameters</h3>
<pre><code class="language-javascript">function createUser(firstName, lastName, ...metadata) {
  return {
    name: firstName + " " + lastName,
    meta: metadata
  };
}

const user = createUser(
  "John",
  "Doe",
  { role: "admin" },
  { permissions: ["read", "write"] }
);

console.log(user);
// {
//   name: "John Doe",
//   meta: [{ role: "admin" }, { permissions: ["read", "write"] }]
// }
</code></pre>
<h3>Spread in Conditional Logic</h3>
<pre><code class="language-javascript">const features = ["auth", "api"];
const allFeatures = ["auth", "api", "admin", "logging"];

// Check if all features are included
const hasAllFeatures = features.every(f =&gt; allFeatures.includes(f));

// Or, spread and use includes
const isSubset = [...features].every(f =&gt; allFeatures.includes(f));
</code></pre>
<hr />
<h2>Common Mistakes</h2>
<h3>Mistake 1: Using Rest in Wrong Position</h3>
<pre><code class="language-javascript">// WRONG - rest must be last
function test(a, ...rest, b) { }

// RIGHT
function test(a, b, ...rest) { }
</code></pre>
<p>Rest collects all remaining values. It must be last.</p>
<h3>Mistake 2: Confusing Spread and Rest by Symbol</h3>
<pre><code class="language-javascript">// WRONG - looks the same but different meaning
const arr = [...[1, 2, 3]];  // Spread - unpacking
const fn = (...args) =&gt; {};  // Rest - collecting

// RIGHT - understand the context
// In array/call: spread
// In parameters/destructuring: rest
</code></pre>
<h3>Mistake 3: Deep Copy with Spread</h3>
<pre><code class="language-javascript">const original = { user: { name: "John" } };

// WRONG - only shallow copy
const copy = { ...original };
copy.user.name = "Jane";

console.log(original.user.name);  // "Jane" (changed!)

// RIGHT - for nested objects, use deep copy or spread nested objects
const deepCopy = {
  ...original,
  user: { ...original.user }
};
</code></pre>
<p>Spread only does shallow copying.</p>
<h3>Mistake 4: Spreading Non-Iterables</h3>
<pre><code class="language-javascript">// WRONG - numbers are not iterable
const num = 123;
const arr = [...num];  // TypeError

// RIGHT - only spread iterables (arrays, strings, objects with Symbol.iterator)
const str = "hello";
const arr = [...str];  // ["h", "e", "l", "l", "o"]
</code></pre>
<h3>Mistake 5: Rest in Middle of Destructuring</h3>
<pre><code class="language-javascript">// WRONG - rest must be last
const { a, ...rest, b } = obj;

// RIGHT
const { a, b, ...rest } = obj;
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Spread operator (<code>...</code>)</strong> in array/object literals or function calls: Expands elements.</p>
<ul>
<li><code>console.log(...[1,2,3])</code> → prints <code>1 2 3</code></li>
<li><code>Math.max(...[5,6,2])</code> → returns <code>6</code></li>
<li><code>{...obj}</code> → creates a copy</li>
</ul>
</li>
<li><p><strong>Rest operator (<code>...</code>)</strong> in function parameters or destructuring: Collects values into an array.</p>
<ul>
<li><code>function(...args)</code> → collects all arguments</li>
<li><code>const [a, ...rest] = arr</code> → collects remaining elements</li>
<li><code>const { name, ...rest } = obj</code> → collects remaining properties</li>
</ul>
</li>
<li><p><strong>Context determines meaning:</strong></p>
<ul>
<li>In arrays/calls: Spread (unpacking)</li>
<li>In parameters/destructuring: Rest (collecting)</li>
</ul>
</li>
<li><p><strong>Spread uses:</strong></p>
<ul>
<li>Copy arrays and objects</li>
<li>Merge arrays and objects</li>
<li>Pass array elements as function arguments</li>
<li>Insert elements into arrays</li>
</ul>
</li>
<li><p><strong>Rest uses:</strong></p>
<ul>
<li>Accept variable number of arguments</li>
<li>Destructure arrays and objects</li>
<li>Extract specific values and collect the rest</li>
</ul>
</li>
<li><p><strong>Spread is shallow</strong> - nested objects/arrays aren't fully copied.</p>
</li>
<li><p><strong>Rest must be last</strong> - it collects all remaining values.</p>
</li>
</ul>
<p>Master spread and rest. Write cleaner, more flexible code. You'll use them constantly.</p>
<p>Happy coding! 🚀</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. 🔗 Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[String Polyfills and Common Interview Methods in JavaScript
]]></title><description><![CDATA[Every JavaScript developer uses string methods. But do you know how they work? Building your own string utilities is more than an interview trick—it's how you truly understand JavaScript. And understa]]></description><link>https://blog.harshx.in/string-polyfills-in-js</link><guid isPermaLink="true">https://blog.harshx.in/string-polyfills-in-js</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 10:16:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/b08f5e85-f0b9-4528-a89c-4225fabe7879.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Every JavaScript developer uses string methods. But do you know how they work? Building your own string utilities is more than an interview trick—it's how you truly understand JavaScript. And understanding them deeply makes you a better developer.</p>
<p>This is about how string methods work, why developers write polyfills, and how to ace those string manipulation interview questions.</p>
<hr />
<h2>What Are String Methods?</h2>
<p>String methods are functions that operate on strings. JavaScript has many built-in.</p>
<h3>Built-In String Methods</h3>
<pre><code class="language-javascript">const str = "Hello";

str.length           // 5
str.toUpperCase()    // "HELLO"
str.toLowerCase()    // "hello"
str.charAt(0)        // "H"
str.indexOf("e")     // 1
str.slice(0, 3)      // "Hel"
str.trim()           // Removes whitespace
</code></pre>
<p>These methods are available on every string. You've used them a thousand times.</p>
<h3>How Methods Work Conceptually</h3>
<p>Every string has methods attached to it. When you call a method, JavaScript:</p>
<ol>
<li>Takes the string as context (<code>this</code>)</li>
<li>Performs an operation</li>
<li>Returns a result</li>
</ol>
<pre><code class="language-plaintext">"hello".toUpperCase()
    ↓
1. this = "hello"
2. Convert all letters to uppercase
3. Return "HELLO"
</code></pre>
<h3>String Methods Are Just Functions</h3>
<p>Under the hood, a string method is just a function that:</p>
<ul>
<li>Accesses the string's characters</li>
<li>Does something with them</li>
<li>Returns a result</li>
</ul>
<p>Understanding this is key. Once you know how they work, you can build them.</p>
<hr />
<h2>How Strings Actually Work</h2>
<p>Before writing polyfills, understand how strings are structured.</p>
<h3>Strings Are Character Arrays</h3>
<p>A string is a sequence of characters. You can access each character by index:</p>
<pre><code class="language-javascript">const str = "Hello";

str[0]  // "H"
str[1]  // "e"
str[2]  // "l"
str[3]  // "l"
str[4]  // "o"
</code></pre>
<p>Each character has a position (index). Index 0 is the first character.</p>
<h3>Strings Have a Length</h3>
<pre><code class="language-javascript">const str = "Hello";
str.length  // 5
</code></pre>
<p>You can iterate through all characters:</p>
<pre><code class="language-javascript">for (let i = 0; i &lt; str.length; i++) {
  console.log(str[i]);
}

// Output:
// H
// e
// l
// l
// o
</code></pre>
<h3>Strings Are Immutable</h3>
<p>Once created, you can't change a string. Methods return new strings:</p>
<pre><code class="language-javascript">const original = "hello";
const upper = original.toUpperCase();

console.log(original); // "hello" (unchanged)
console.log(upper);    // "HELLO" (new string)
</code></pre>
<p>This is crucial for polyfills. You always create and return new strings.</p>
<hr />
<h2>What Is a Polyfill?</h2>
<p>A polyfill is code that replicates the functionality of a built-in method.</p>
<h3>Why Write Polyfills?</h3>
<p><strong>Reason 1: Compatibility</strong></p>
<p>Some older browsers don't have newer methods. A polyfill provides that functionality:</p>
<pre><code class="language-javascript">// Modern method
const trimmed = "  hello  ".trimStart();

// If the browser doesn't support trimStart(), use a polyfill
function trimStart(str) {
  let start = 0;
  while (str[start] === " ") {
    start++;
  }
  return str.slice(start);
}
</code></pre>
<p><strong>Reason 2: Understanding</strong></p>
<p>Writing a polyfill forces you to understand the logic. Interview questions often ask this.</p>
<p><strong>Reason 3: Custom Behavior</strong></p>
<p>Sometimes you need a slight variation:</p>
<pre><code class="language-javascript">// Built-in returns the first occurrence
"hello".indexOf("l");  // 2

// Your polyfill could return all occurrences
function findAll(str, char) {
  const indices = [];
  for (let i = 0; i &lt; str.length; i++) {
    if (str[i] === char) {
      indices.push(i);
    }
  }
  return indices;
}

findAll("hello", "l");  // [2, 3]
</code></pre>
<h3>Polyfill Structure</h3>
<p>Every polyfill follows a pattern:</p>
<pre><code class="language-javascript">function myPolyfill(input, ...args) {
  // 1. Validate input
  // 2. Initialize variables
  // 3. Iterate through the string (or other logic)
  // 4. Build the result
  // 5. Return the result
}
</code></pre>
<p>Let's build some.</p>
<hr />
<h2>Implementing Simple String Utilities</h2>
<h3>1. Uppercase Polyfill</h3>
<p>The logic: Convert each letter to uppercase.</p>
<pre><code class="language-javascript">function toUpperCase(str) {
  let result = "";
  
  for (let i = 0; i &lt; str.length; i++) {
    const char = str[i];
    // ASCII: lowercase a-z is 97-122, uppercase A-Z is 65-90
    // Difference is 32
    if (char &gt;= "a" &amp;&amp; char &lt;= "z") {
      // Convert lowercase to uppercase
      result += String.fromCharCode(char.charCodeAt(0) - 32);
    } else {
      // Keep non-lowercase characters as-is
      result += char;
    }
  }
  
  return result;
}

toUpperCase("hello");     // "HELLO"
toUpperCase("Hello 123"); // "HELLO 123"
toUpperCase("WORLD");     // "WORLD"
</code></pre>
<p><strong>How it works:</strong></p>
<ol>
<li>Loop through each character</li>
<li>Check if it's lowercase (a-z)</li>
<li>If yes, convert to uppercase using ASCII codes</li>
<li>If no, keep it as-is</li>
<li>Build and return the result</li>
</ol>
<h3>2. Lowercase Polyfill</h3>
<p>Similar logic, opposite direction:</p>
<pre><code class="language-javascript">function toLowerCase(str) {
  let result = "";
  
  for (let i = 0; i &lt; str.length; i++) {
    const char = str[i];
    if (char &gt;= "A" &amp;&amp; char &lt;= "Z") {
      // Convert uppercase to lowercase
      result += String.fromCharCode(char.charCodeAt(0) + 32);
    } else {
      result += char;
    }
  }
  
  return result;
}

toLowerCase("HELLO");     // "hello"
toLowerCase("Hello 123"); // "hello 123"
</code></pre>
<h3>3. indexOf Polyfill</h3>
<p>Find the first occurrence of a substring:</p>
<pre><code class="language-javascript">function indexOf(str, searchStr, fromIndex = 0) {
  // Start from fromIndex (or 0 if not provided)
  for (let i = fromIndex; i &lt; str.length; i++) {
    // Check if searchStr matches starting at position i
    let match = true;
    
    for (let j = 0; j &lt; searchStr.length; j++) {
      if (str[i + j] !== searchStr[j]) {
        match = false;
        break;
      }
    }
    
    if (match) {
      return i; // Found it, return the index
    }
  }
  
  return -1; // Not found
}

indexOf("hello world", "o");      // 4
indexOf("hello world", "world");  // 6
indexOf("hello world", "xyz");    // -1
indexOf("hello hello", "ello", 2); // 5
</code></pre>
<p><strong>How it works:</strong></p>
<ol>
<li>Loop through each position in the string</li>
<li>At each position, check if the substring matches</li>
<li>To check, compare character by character</li>
<li>If all match, return the index</li>
<li>If nothing matches, return -1</li>
</ol>
<h3>4. slice Polyfill</h3>
<p>Extract a portion of the string:</p>
<pre><code class="language-javascript">function slice(str, start = 0, end = str.length) {
  // Handle negative indices
  if (start &lt; 0) start = Math.max(0, str.length + start);
  if (end &lt; 0) end = Math.max(0, str.length + end);
  
  // Clamp to string boundaries
  start = Math.max(0, start);
  end = Math.min(str.length, end);
  
  let result = "";
  
  for (let i = start; i &lt; end; i++) {
    result += str[i];
  }
  
  return result;
}

slice("hello", 0, 3);    // "hel"
slice("hello", 1);       // "ello"
slice("hello", -3);      // "llo"
slice("hello", -4, -1);  // "ell"
</code></pre>
<p><strong>How it works:</strong></p>
<ol>
<li>Handle negative indices (count from the end)</li>
<li>Clamp values to string boundaries</li>
<li>Loop from start to end</li>
<li>Collect characters and return</li>
</ol>
<h3>5. includes Polyfill</h3>
<p>Check if a string contains a substring:</p>
<pre><code class="language-javascript">function includes(str, searchStr, position = 0) {
  // Start searching from position
  for (let i = position; i &lt; str.length; i++) {
    // Try to match searchStr at position i
    let match = true;
    
    for (let j = 0; j &lt; searchStr.length; j++) {
      if (str[i + j] !== searchStr[j]) {
        match = false;
        break;
      }
    }
    
    if (match) {
      return true;
    }
  }
  
  return false;
}

includes("hello world", "world");  // true
includes("hello world", "xyz");    // false
includes("hello world", "ell", 1); // true
</code></pre>
<h3>6. split Polyfill</h3>
<p>Split a string by a delimiter:</p>
<pre><code class="language-javascript">function split(str, delimiter = "", limit) {
  const result = [];
  
  if (delimiter === "") {
    // Split into individual characters
    for (let i = 0; i &lt; str.length; i++) {
      if (limit !== undefined &amp;&amp; result.length &gt;= limit) break;
      result.push(str[i]);
    }
  } else {
    let current = "";
    let i = 0;
    
    while (i &lt; str.length) {
      // Check if delimiter matches at position i
      let match = true;
      for (let j = 0; j &lt; delimiter.length; j++) {
        if (str[i + j] !== delimiter[j]) {
          match = false;
          break;
        }
      }
      
      if (match) {
        // Delimiter found
        result.push(current);
        if (limit !== undefined &amp;&amp; result.length &gt;= limit) {
          return result;
        }
        current = "";
        i += delimiter.length;
      } else {
        // Not a match, add character to current
        current += str[i];
        i++;
      }
    }
    
    result.push(current); // Add the last part
  }
  
  return result;
}

split("hello", "");        // ["h", "e", "l", "l", "o"]
split("a,b,c", ",");       // ["a", "b", "c"]
split("hello", "l");       // ["he", "", "o"]
split("a,b,c,d", ",", 2);  // ["a", "b"]
</code></pre>
<h3>7. trim Polyfill</h3>
<p>Remove whitespace from both ends:</p>
<pre><code class="language-javascript">function trim(str) {
  let start = 0;
  let end = str.length - 1;
  
  // Find first non-whitespace character
  while (start &lt;= end &amp;&amp; str[start] === " ") {
    start++;
  }
  
  // Find last non-whitespace character
  while (end &gt;= start &amp;&amp; str[end] === " ") {
    end--;
  }
  
  // Return the trimmed string
  return str.slice(start, end + 1);
}

trim("  hello  ");     // "hello"
trim("hello");         // "hello"
trim("  ");            // ""
trim("  a b c  ");     // "a b c"
</code></pre>
<p><strong>How it works:</strong></p>
<ol>
<li>Find the first non-space character from the left</li>
<li>Find the first non-space character from the right</li>
<li>Extract the substring between them</li>
</ol>
<h3>8. repeat Polyfill</h3>
<p>Repeat a string multiple times:</p>
<pre><code class="language-javascript">function repeat(str, count) {
  // Validate count
  if (count &lt; 0 || count === Infinity) {
    throw new Error("Invalid count value");
  }
  
  let result = "";
  
  for (let i = 0; i &lt; count; i++) {
    result += str;
  }
  
  return result;
}

repeat("ab", 3);    // "ababab"
repeat("hello", 2); // "hellohello"
repeat("x", 0);     // ""
</code></pre>
<h3>9. replace Polyfill</h3>
<p>Replace the first occurrence of a substring:</p>
<pre><code class="language-javascript">function replace(str, searchStr, replaceStr) {
  // Find the first occurrence
  for (let i = 0; i &lt; str.length; i++) {
    let match = true;
    
    // Check if searchStr matches at position i
    for (let j = 0; j &lt; searchStr.length; j++) {
      if (str[i + j] !== searchStr[j]) {
        match = false;
        break;
      }
    }
    
    if (match) {
      // Found it, replace and return
      return str.slice(0, i) + replaceStr + str.slice(i + searchStr.length);
    }
  }
  
  // Not found, return original
  return str;
}

replace("hello world", "world", "universe"); // "hello universe"
replace("hello hello", "hello", "hi");       // "hi hello"
replace("hello", "xyz", "abc");              // "hello"
</code></pre>
<h3>10. startsWith Polyfill</h3>
<p>Check if a string starts with a substring:</p>
<pre><code class="language-javascript">function startsWith(str, searchStr, position = 0) {
  // Check if str starts with searchStr from position
  for (let i = 0; i &lt; searchStr.length; i++) {
    if (str[position + i] !== searchStr[i]) {
      return false;
    }
  }
  return true;
}

startsWith("hello", "he");      // true
startsWith("hello", "ell");     // false
startsWith("hello", "ell", 1);  // true
startsWith("hello", "");        // true
</code></pre>
<hr />
<h2>String Processing Flow</h2>
<p>Here's how string methods conceptually work:</p>
<pre><code class="language-plaintext">Input String
    ↓
Method receives it
    ↓
Initialize result container
    ↓
Loop through characters
    ↓
    ├─ Evaluate each character
    ├─ Apply logic
    └─ Add to result
    ↓
Return new string
</code></pre>
<h3>Visual Example: indexOf</h3>
<pre><code class="language-plaintext">String: "hello world"
Search: "o"

Position 0: "h" vs "o" → No match
Position 1: "e" vs "o" → No match
Position 2: "l" vs "o" → No match
Position 3: "l" vs "o" → No match
Position 4: "o" vs "o" → MATCH!

Return: 4
</code></pre>
<h3>Visual Example: split</h3>
<pre><code class="language-plaintext">String: "a,b,c"
Delimiter: ","

Position 0: "a" → Not delimiter → Add to current
Position 1: "," → DELIMITER → Push "a" to result, reset
Position 2: "b" → Not delimiter → Add to current
Position 3: "," → DELIMITER → Push "b" to result, reset
Position 4: "c" → Not delimiter → Add to current
End of string → Push "c" to result

Result: ["a", "b", "c"]
</code></pre>
<hr />
<h2>Common Interview String Problems</h2>
<h3>Problem 1: Reverse a String</h3>
<p><strong>Question:</strong> Write a function to reverse a string.</p>
<pre><code class="language-javascript">function reverseString(str) {
  let result = "";
  
  for (let i = str.length - 1; i &gt;= 0; i--) {
    result += str[i];
  }
  
  return result;
}

reverseString("hello");  // "olleh"
reverseString("12345");  // "54321"
</code></pre>
<p><strong>Alternative:</strong> Using built-in methods</p>
<pre><code class="language-javascript">function reverseString(str) {
  return str.split("").reverse().join("");
}
</code></pre>
<h3>Problem 2: Check for Palindrome</h3>
<p><strong>Question:</strong> Check if a string is a palindrome.</p>
<pre><code class="language-javascript">function isPalindrome(str) {
  // Remove spaces and convert to lowercase
  const clean = str.toLowerCase().replace(/\s/g, "");
  
  // Compare with reversed version
  let reversed = "";
  for (let i = clean.length - 1; i &gt;= 0; i--) {
    reversed += clean[i];
  }
  
  return clean === reversed;
}

isPalindrome("racecar");      // true
isPalindrome("race car");     // true
isPalindrome("hello");        // false
</code></pre>
<p><strong>Alternative:</strong> Two-pointer approach</p>
<pre><code class="language-javascript">function isPalindrome(str) {
  const clean = str.toLowerCase().replace(/\s/g, "");
  let left = 0;
  let right = clean.length - 1;
  
  while (left &lt; right) {
    if (clean[left] !== clean[right]) {
      return false;
    }
    left++;
    right--;
  }
  
  return true;
}
</code></pre>
<h3>Problem 3: Count Character Frequency</h3>
<p><strong>Question:</strong> Count how many times each character appears.</p>
<pre><code class="language-javascript">function countCharacters(str) {
  const count = {};
  
  for (let i = 0; i &lt; str.length; i++) {
    const char = str[i];
    count[char] = (count[char] || 0) + 1;
  }
  
  return count;
}

countCharacters("hello");
// { h: 1, e: 1, l: 2, o: 1 }

countCharacters("aabbcc");
// { a: 2, b: 2, c: 2 }
</code></pre>
<h3>Problem 4: Find the First Non-Repeated Character</h3>
<p><strong>Question:</strong> Find the first character that appears only once.</p>
<pre><code class="language-javascript">function firstNonRepeated(str) {
  const count = {};
  
  // Count all characters
  for (let i = 0; i &lt; str.length; i++) {
    const char = str[i];
    count[char] = (count[char] || 0) + 1;
  }
  
  // Find first character with count 1
  for (let i = 0; i &lt; str.length; i++) {
    if (count[str[i]] === 1) {
      return str[i];
    }
  }
  
  return null;
}

firstNonRepeated("hello");      // "h"
firstNonRepeated("aabbcc");     // null
firstNonRepeated("aabbc");      // "c"
</code></pre>
<h3>Problem 5: Anagram Check</h3>
<p><strong>Question:</strong> Check if two strings are anagrams.</p>
<pre><code class="language-javascript">function isAnagram(str1, str2) {
  // Remove spaces and convert to lowercase
  const clean1 = str1.toLowerCase().replace(/\s/g, "");
  const clean2 = str2.toLowerCase().replace(/\s/g, "");
  
  // Check if lengths match
  if (clean1.length !== clean2.length) {
    return false;
  }
  
  // Count characters in first string
  const count = {};
  for (let i = 0; i &lt; clean1.length; i++) {
    const char = clean1[i];
    count[char] = (count[char] || 0) + 1;
  }
  
  // Check if characters match in second string
  for (let i = 0; i &lt; clean2.length; i++) {
    const char = clean2[i];
    if (!count[char]) {
      return false;
    }
    count[char]--;
  }
  
  return true;
}

isAnagram("listen", "silent");      // true
isAnagram("hello", "world");        // false
isAnagram("abc", "bca");            // true
</code></pre>
<p><strong>Alternative:</strong> Sorting approach</p>
<pre><code class="language-javascript">function isAnagram(str1, str2) {
  const sort1 = str1.toLowerCase().replace(/\s/g, "").split("").sort().join("");
  const sort2 = str2.toLowerCase().replace(/\s/g, "").split("").sort().join("");
  return sort1 === sort2;
}
</code></pre>
<h3>Problem 6: String Compression</h3>
<p><strong>Question:</strong> Compress a string by replacing repeated characters with count.</p>
<pre><code class="language-javascript">function compress(str) {
  if (str.length &lt;= 2) return str;
  
  let result = "";
  let count = 1;
  
  for (let i = 0; i &lt; str.length; i++) {
    // If next character is different or we're at the end
    if (str[i] !== str[i + 1]) {
      result += str[i] + count;
      count = 1;
    } else {
      count++;
    }
  }
  
  return result.length &lt; str.length ? result : str;
}

compress("aabbcc");      // "a2b2c2"
compress("abcdef");      // "abcdef" (no compression)
compress("aaaa");        // "a4"
</code></pre>
<h3>Problem 7: Word Frequency</h3>
<p><strong>Question:</strong> Count how many times each word appears.</p>
<pre><code class="language-javascript">function wordFrequency(str) {
  const words = str.toLowerCase().split(/\s+/);
  const count = {};
  
  for (let i = 0; i &lt; words.length; i++) {
    const word = words[i];
    count[word] = (count[word] || 0) + 1;
  }
  
  return count;
}

wordFrequency("hello world hello");
// { hello: 2, world: 1 }
</code></pre>
<h3>Problem 8: Longest Substring Without Repeating Characters</h3>
<p><strong>Question:</strong> Find the length of the longest substring without repeating characters.</p>
<pre><code class="language-javascript">function longestSubstring(str) {
  let maxLength = 0;
  let currentLength = 0;
  const charIndex = {};
  
  for (let i = 0; i &lt; str.length; i++) {
    const char = str[i];
    
    // If character was seen and is in current window
    if (charIndex[char] !== undefined &amp;&amp; charIndex[char] &gt;= (i - currentLength)) {
      // Reset length
      currentLength = i - charIndex[char] - 1;
    } else {
      currentLength++;
    }
    
    charIndex[char] = i;
    maxLength = Math.max(maxLength, currentLength);
  }
  
  return maxLength;
}

longestSubstring("abcabcbb");  // 3 ("abc")
longestSubstring("bbbbb");     // 1 ("b")
longestSubstring("pwwkew");    // 3 ("kew")
</code></pre>
<hr />
<h2>Why Understanding Built-In Behavior Matters</h2>
<h3>Interview Preparation</h3>
<p>Interviewers ask you to build string methods for a reason:</p>
<ol>
<li><strong>It shows understanding</strong> - You know how strings work at a fundamental level</li>
<li><strong>It tests logic</strong> - You can think through problems algorithmically</li>
<li><strong>It reveals gaps</strong> - Edge cases in your implementation show what you miss</li>
<li><strong>It's practical</strong> - You can debug better when things go wrong</li>
</ol>
<h3>Real-World Application</h3>
<p>Understanding how methods work helps you:</p>
<ol>
<li><strong>Debug faster</strong> - When something goes wrong, you understand why</li>
<li><strong>Optimize</strong> - You know the cost of operations</li>
<li><strong>Choose wisely</strong> - Pick the right method for the job</li>
<li><strong>Extend functionality</strong> - Build custom methods when needed</li>
</ol>
<h3>Edge Cases Show Deep Understanding</h3>
<pre><code class="language-javascript">// A shallow implementation
function includes(str, search) {
  return str.indexOf(search) !== -1;
}

// A deep implementation handles edge cases
function includes(str, search, position = 0) {
  if (search === "") return true;         // Empty string is always included
  if (position &gt;= str.length) return false; // Position out of bounds
  if (search.length &gt; str.length) return false; // Search longer than string
  
  // ... actual logic
}
</code></pre>
<p>The difference is understanding the edge cases.</p>
<hr />
<h2>Polyfill Behavior Representation</h2>
<pre><code class="language-plaintext">Built-in Method
    ↓
Input Validation
    ↓
    ├─ Check arguments
    ├─ Handle defaults
    └─ Validate types
    ↓
Core Logic
    ↓
    ├─ Loop through string
    ├─ Apply transformations
    └─ Build result
    ↓
Result Assembly
    ↓
    ├─ Combine parts
    ├─ Format output
    └─ Handle edge cases
    ↓
Return Result
</code></pre>
<p>Every polyfill follows this pattern.</p>
<hr />
<h2>String Method Comparison Table</h2>
<table>
<thead>
<tr>
<th>Method</th>
<th>Purpose</th>
<th>Input</th>
<th>Output</th>
</tr>
</thead>
<tbody><tr>
<td>toUpperCase</td>
<td>Convert to uppercase</td>
<td>string</td>
<td>string</td>
</tr>
<tr>
<td>toLowerCase</td>
<td>Convert to lowercase</td>
<td>string</td>
<td>string</td>
</tr>
<tr>
<td>indexOf</td>
<td>Find first occurrence</td>
<td>string, search, position</td>
<td>number</td>
</tr>
<tr>
<td>slice</td>
<td>Extract substring</td>
<td>string, start, end</td>
<td>string</td>
</tr>
<tr>
<td>includes</td>
<td>Check if contains</td>
<td>string, search, position</td>
<td>boolean</td>
</tr>
<tr>
<td>split</td>
<td>Split by delimiter</td>
<td>string, delimiter, limit</td>
<td>array</td>
</tr>
<tr>
<td>trim</td>
<td>Remove whitespace</td>
<td>string</td>
<td>string</td>
</tr>
<tr>
<td>repeat</td>
<td>Repeat string</td>
<td>string, count</td>
<td>string</td>
</tr>
<tr>
<td>replace</td>
<td>Replace occurrence</td>
<td>string, search, replace</td>
<td>string</td>
</tr>
<tr>
<td>startsWith</td>
<td>Check start</td>
<td>string, search, position</td>
<td>boolean</td>
</tr>
</tbody></table>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Implement charAt:</strong></p>
<pre><code class="language-javascript">function charAt(str, index) {
  // Return the character at the given index
  // Return empty string if out of bounds
}

charAt("hello", 0);  // "h"
charAt("hello", 5);  // ""
</code></pre>
<p><strong>2. Implement lastIndexOf:</strong></p>
<pre><code class="language-javascript">function lastIndexOf(str, searchStr) {
  // Find the LAST occurrence of searchStr
  // Return -1 if not found
}

lastIndexOf("hello", "l");     // 3
lastIndexOf("hello", "hello"); // 0
</code></pre>
<p><strong>3. Implement endsWith:</strong></p>
<pre><code class="language-javascript">function endsWith(str, searchStr, length) {
  // Check if str ends with searchStr
  // Optional length parameter
}

endsWith("hello", "lo");   // true
endsWith("hello", "ll");   // false
</code></pre>
<p><strong>4. Solve a common problem:</strong></p>
<p>Choose one:</p>
<ul>
<li>Reverse a string</li>
<li>Check palindrome</li>
<li>Count character frequency</li>
<li>Find first non-repeated character</li>
<li>Check anagram</li>
</ul>
<p><strong>5. Implement replaceAll:</strong></p>
<pre><code class="language-javascript">function replaceAll(str, searchStr, replaceStr) {
  // Replace ALL occurrences (not just the first)
}

replaceAll("hello hello", "hello", "hi");  // "hi hi"
replaceAll("aaa", "a", "b");                // "bbb"
</code></pre>
<hr />
<h2>Common Mistakes</h2>
<h3>Mistake 1: Forgetting String Immutability</h3>
<pre><code class="language-javascript">// WRONG - trying to modify a string
let str = "hello";
str[0] = "H";
console.log(str); // "hello" (unchanged)

// RIGHT - create a new string
function capitalize(str) {
  return str[0].toUpperCase() + str.slice(1);
}
</code></pre>
<h3>Mistake 2: Off-by-One Errors</h3>
<pre><code class="language-javascript">// WRONG - loop goes one too far
for (let i = 0; i &lt;= str.length; i++) {
  // Accesses str[str.length] which is undefined
}

// RIGHT
for (let i = 0; i &lt; str.length; i++) {
  // Safe access
}
</code></pre>
<h3>Mistake 3: Not Handling Empty Strings</h3>
<pre><code class="language-javascript">// WRONG - crashes on empty string
function firstChar(str) {
  return str[0].toUpperCase(); // Error if str is ""
}

// RIGHT
function firstChar(str) {
  if (str.length === 0) return "";
  return str[0].toUpperCase();
}
</code></pre>
<h3>Mistake 4: Ignoring Edge Cases</h3>
<pre><code class="language-javascript">// WRONG - doesn't handle negatives
function slice(str, start, end) {
  // What if start is negative?
}

// RIGHT
function slice(str, start = 0, end = str.length) {
  if (start &lt; 0) start = Math.max(0, str.length + start);
  if (end &lt; 0) end = Math.max(0, str.length + end);
  // ... continue
}
</code></pre>
<h3>Mistake 5: Inefficient Concatenation</h3>
<pre><code class="language-javascript">// SLOW - creates new string each iteration
function repeat(str, count) {
  let result = "";
  for (let i = 0; i &lt; count; i++) {
    result += str; // Creates new string each time
  }
  return result;
}

// BETTER - still works, same approach is fine for interviews
// For production, consider array join method
function repeat(str, count) {
  let result = "";
  for (let i = 0; i &lt; count; i++) {
    result += str;
  }
  return result;
}
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>String methods</strong> are built-in functions that operate on strings.</p>
</li>
<li><p><strong>Strings are sequences of characters</strong> that you can access by index.</p>
</li>
<li><p><strong>Strings are immutable</strong> - methods return new strings, not modify the original.</p>
</li>
<li><p><strong>A polyfill replicates</strong> the functionality of a built-in method.</p>
</li>
<li><p><strong>Why polyfills matter:</strong></p>
<ul>
<li>Understand how built-ins work</li>
<li>Prepare for interviews</li>
<li>Provide fallbacks for older browsers</li>
</ul>
</li>
<li><p><strong>Core pattern for any polyfill:</strong></p>
<ol>
<li>Validate input</li>
<li>Initialize result</li>
<li>Loop and process</li>
<li>Return result</li>
</ol>
</li>
<li><p><strong>Common interview problems:</strong></p>
<ul>
<li>Reverse string</li>
<li>Palindrome check</li>
<li>Character frequency</li>
<li>Anagram detection</li>
<li>String compression</li>
<li>Substring without repeating chars</li>
</ul>
</li>
<li><p><strong>Edge cases matter</strong> - empty strings, negative indices, out-of-bounds access.</p>
</li>
<li><p><strong>Built-in behavior understanding</strong> helps you:</p>
<ul>
<li>Debug faster</li>
<li>Choose the right method</li>
<li>Optimize code</li>
<li>Pass interviews</li>
</ul>
</li>
</ul>
<p>Build your own string methods. Understand how they work. Master the fundamentals.</p>
<p>Happy coding! 🚀</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. 🔗 Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[Setting Up Your First Node.js Application Step-by-Step
]]></title><description><![CDATA[Node.js is JavaScript outside the browser. You can run JavaScript on your computer, on servers, and in the cloud. Getting started is simpler than you think. This guide walks you through everything fro]]></description><link>https://blog.harshx.in/setting-up-node-js</link><guid isPermaLink="true">https://blog.harshx.in/setting-up-node-js</guid><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCohort]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 10:09:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/b7299c67-93c7-450a-a4bb-a28f24fd9f9f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Node.js is JavaScript outside the browser. You can run JavaScript on your computer, on servers, and in the cloud. Getting started is simpler than you think. This guide walks you through everything from zero.</p>
<p>This is about installing Node.js, understanding what it does, running your first script, and building your first server.</p>
<hr />
<h2>What Is Node.js?</h2>
<p>Node.js is a JavaScript runtime. It lets you run JavaScript code outside the browser.</p>
<h3>JavaScript Before Node.js</h3>
<pre><code class="language-plaintext">Browser
    ↓
  JavaScript engine
    ↓
  Runs scripts, handles DOM, events
</code></pre>
<p>JavaScript was trapped in the browser. You needed a browser to run JavaScript.</p>
<h3>JavaScript with Node.js</h3>
<pre><code class="language-plaintext">Computer / Server
    ↓
  Node.js (JavaScript runtime)
    ↓
  Runs scripts, handles files, networks, databases
</code></pre>
<p>Now JavaScript runs anywhere. No browser needed.</p>
<h3>What Can Node.js Do?</h3>
<ul>
<li>Create web servers</li>
<li>Read and write files</li>
<li>Make HTTP requests</li>
<li>Connect to databases</li>
<li>Run command-line tools</li>
<li>Build APIs</li>
<li>Process data</li>
</ul>
<p>Basically anything a server-side language can do.</p>
<hr />
<h2>Installing Node.js</h2>
<p>Node.js is free and open-source. Installation takes 2 minutes.</p>
<h3>Step 1: Go to nodejs.org</h3>
<p>Visit <a href="https://nodejs.org/">https://nodejs.org/</a></p>
<p>You'll see two versions:</p>
<pre><code class="language-plaintext">LTS (Long Term Support)  ← Recommended for beginners
Current                  ← Latest features, less stable
</code></pre>
<p>Download the LTS version. It's stable and supported for years.</p>
<h3>Step 2: Run the Installer</h3>
<p><strong>Windows:</strong></p>
<ol>
<li>Download the <code>.msi</code> file</li>
<li>Run the installer</li>
<li>Click "Next" through the steps</li>
<li>Click "Install"</li>
<li>Click "Finish"</li>
</ol>
<p><strong>macOS:</strong></p>
<ol>
<li>Download the <code>.pkg</code> file</li>
<li>Run the installer</li>
<li>Follow the prompts</li>
<li>Done</li>
</ol>
<p><strong>Linux (Ubuntu/Debian):</strong></p>
<pre><code class="language-bash">curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs
</code></pre>
<p>Or use your package manager.</p>
<h3>Step 3: Verify Installation</h3>
<p>Open a terminal/command prompt and type:</p>
<pre><code class="language-bash">node --version
</code></pre>
<p>You should see:</p>
<pre><code class="language-plaintext">v20.10.0
</code></pre>
<p>(The exact version doesn't matter, just that it shows a version.)</p>
<p>Also check npm:</p>
<pre><code class="language-bash">npm --version
</code></pre>
<p>You should see:</p>
<pre><code class="language-plaintext">10.2.3
</code></pre>
<p>Both commands working? Node.js is installed. You're done.</p>
<hr />
<h2>Understanding the Terminal</h2>
<p>You'll need to use the terminal (command line) to run Node.js scripts.</p>
<h3>Opening the Terminal</h3>
<p><strong>Windows:</strong></p>
<ul>
<li>Press <code>Win + R</code></li>
<li>Type <code>cmd</code></li>
<li>Press Enter</li>
</ul>
<p><strong>macOS:</strong></p>
<ul>
<li>Press <code>Cmd + Space</code></li>
<li>Type <code>terminal</code></li>
<li>Press Enter</li>
</ul>
<p><strong>Linux:</strong></p>
<ul>
<li>Ctrl + Alt + T</li>
<li>Or search for "Terminal"</li>
</ul>
<h3>Basic Commands</h3>
<pre><code class="language-bash">pwd                 # Print working directory (where you are)
ls                  # List files in current directory
cd folder_name      # Change directory (go into a folder)
cd ..               # Go up one level
mkdir folder_name   # Make a new folder
</code></pre>
<h3>Example</h3>
<pre><code class="language-bash">pwd
# Output: /Users/john/Documents

ls
# Output: Desktop  Documents  Downloads

cd Documents
# Now you're in Documents folder

pwd
# Output: /Users/john/Documents

mkdir my-app
cd my-app
# Now you're in my-app folder
</code></pre>
<hr />
<h2>The Node REPL</h2>
<p>REPL stands for "Read-Eval-Print-Loop". It's an interactive JavaScript environment.</p>
<h3>What Is REPL?</h3>
<pre><code class="language-plaintext">Read   → You type JavaScript code
Eval   → Node.js evaluates it
Print  → It prints the result
Loop   → Waits for more input
</code></pre>
<p>It's like a JavaScript sandbox where you can test code instantly.</p>
<h3>Starting the REPL</h3>
<p>Type this in your terminal:</p>
<pre><code class="language-bash">node
</code></pre>
<p>You'll see:</p>
<pre><code class="language-plaintext">Welcome to Node.js v20.10.0.
Type ".help" for more information.
&gt;
</code></pre>
<p>The <code>&gt;</code> prompt means Node is waiting for input.</p>
<h3>Using the REPL</h3>
<p>Try some JavaScript:</p>
<pre><code class="language-javascript">&gt; 2 + 2
4
&gt; "hello"
'hello'
&gt; const name = "John"
undefined
&gt; name
'John'
</code></pre>
<p>The REPL evaluates each line and prints the result. <code>undefined</code> is printed when there's nothing to return (like after assignment).</p>
<h3>REPL Examples</h3>
<pre><code class="language-javascript">&gt; const numbers = [1, 2, 3]
undefined

&gt; numbers.length
3

&gt; numbers.map(n =&gt; n * 2)
[ 2, 4, 6 ]

&gt; Math.sqrt(16)
4

&gt; new Date()
2026-05-04T10:30:45.123Z
</code></pre>
<h3>Exiting the REPL</h3>
<p>Type <code>.exit</code> or press <code>Ctrl + D</code>:</p>
<pre><code class="language-javascript">&gt; .exit
</code></pre>
<p>You're back at the terminal prompt.</p>
<h3>REPL Is for Experimenting</h3>
<p>The REPL is great for:</p>
<ul>
<li>Testing code quickly</li>
<li>Learning JavaScript</li>
<li>Debugging</li>
<li>Exploring APIs</li>
</ul>
<p>But for real applications, you write code in files.</p>
<hr />
<h2>Your First Node.js Script</h2>
<p>Let's create a simple JavaScript file and run it with Node.</p>
<h3>Step 1: Create a Folder</h3>
<pre><code class="language-bash">mkdir my-first-app
cd my-first-app
</code></pre>
<p>You're now in a new folder.</p>
<h3>Step 2: Create a JavaScript File</h3>
<p>Create a file named <code>hello.js</code>:</p>
<p><strong>Windows (Command Prompt):</strong></p>
<pre><code class="language-bash">type nul &gt; hello.js
</code></pre>
<p><strong>macOS/Linux:</strong></p>
<pre><code class="language-bash">touch hello.js
</code></pre>
<p>Or use a text editor (VS Code, Sublime Text, etc.) to create the file.</p>
<h3>Step 3: Write Code</h3>
<p>Open <code>hello.js</code> in your text editor and write:</p>
<pre><code class="language-javascript">console.log("Hello, World!");
</code></pre>
<p>Save the file.</p>
<h3>Step 4: Run the Script</h3>
<p>In your terminal (in the same folder), type:</p>
<pre><code class="language-bash">node hello.js
</code></pre>
<p>You'll see:</p>
<pre><code class="language-plaintext">Hello, World!
</code></pre>
<p>Success! You just ran your first Node.js script.</p>
<h3>What Happened?</h3>
<pre><code class="language-plaintext">You type: node hello.js
    ↓
Node reads hello.js
    ↓
Node executes the code
    ↓
console.log() prints to terminal
    ↓
Output: Hello, World!
    ↓
Script finishes, returns to prompt
</code></pre>
<h3>More Examples</h3>
<p><strong>Example 1: Variables and Math</strong></p>
<p>Create <code>math.js</code>:</p>
<pre><code class="language-javascript">const a = 10;
const b = 20;
const sum = a + b;

console.log("Sum:", sum);
console.log("Product:", a * b);
</code></pre>
<p>Run it:</p>
<pre><code class="language-bash">node math.js
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Sum: 30
Product: 200
</code></pre>
<p><strong>Example 2: Arrays and Loops</strong></p>
<p>Create <code>loop.js</code>:</p>
<pre><code class="language-javascript">const fruits = ["apple", "banana", "orange"];

console.log("Fruits:");
for (let fruit of fruits) {
  console.log("- " + fruit);
}
</code></pre>
<p>Run it:</p>
<pre><code class="language-bash">node loop.js
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Fruits:
- apple
- banana
- orange
</code></pre>
<p><strong>Example 3: Functions</strong></p>
<p>Create <code>greet.js</code>:</p>
<pre><code class="language-javascript">function greet(name, age) {
  console.log("Hello, " + name + "!");
  console.log("You are " + age + " years old.");
}

greet("Alice", 25);
greet("Bob", 30);
</code></pre>
<p>Run it:</p>
<pre><code class="language-bash">node greet.js
</code></pre>
<p>Output:</p>
<pre><code class="language-plaintext">Hello, Alice!
You are 25 years old.
Hello, Bob!
You are 30 years old.
</code></pre>
<hr />
<h2>Node.js Execution Flow</h2>
<p>Here's what happens when you run a script.</p>
<h3>Execution Timeline</h3>
<pre><code class="language-plaintext">You type: node hello.js
    ↓
1. Node.js starts
    ↓
2. Reads hello.js
    ↓
3. Parses the code (checks for syntax errors)
    ↓
4. Executes the code line by line
    ↓
5. Encounters console.log()
    ↓
6. Prints output to terminal
    ↓
7. Code finishes
    ↓
8. Node.js exits
    ↓
Back to terminal prompt
</code></pre>
<h3>Script → Runtime → Output Flow</h3>
<pre><code class="language-plaintext">hello.js (file)
    ↓
Node.js Runtime
    ↓
JavaScript Engine (V8)
    ↓
Parse code
    ↓
Execute code
    ↓
Call built-in functions (console.log, etc.)
    ↓
Output: "Hello, World!"
</code></pre>
<h3>Why Files vs REPL?</h3>
<p>REPL is interactive:</p>
<ul>
<li>Type one line</li>
<li>See result immediately</li>
<li>Good for learning</li>
</ul>
<p>Files are permanent:</p>
<ul>
<li>Code is saved</li>
<li>Can run anytime</li>
<li>Easy to share</li>
<li>Good for real projects</li>
</ul>
<hr />
<h2>Writing Your First Server</h2>
<p>Now let's create a real Node.js server. It won't be much, but it's a real web server.</p>
<h3>What Is a Server?</h3>
<p>A server is a program that listens for requests and sends responses.</p>
<pre><code class="language-plaintext">Client (browser/computer)
    ↓
Sends request to server
    ↓
Server
    ↓
Receives request
Processes it
Sends response
    ↓
Client
    ↓
Receives response
</code></pre>
<h3>Hello World Server</h3>
<p>Create <code>server.js</code>:</p>
<pre><code class="language-javascript">const http = require("http");

const server = http.createServer((req, res) =&gt; {
  res.writeHead(200, { "Content-Type": "text/plain" });
  res.end("Hello, World!");
});

server.listen(3000);
console.log("Server running on http://localhost:3000");
</code></pre>
<h3>Running the Server</h3>
<pre><code class="language-bash">node server.js
</code></pre>
<p>You'll see:</p>
<pre><code class="language-plaintext">Server running on http://localhost:3000
</code></pre>
<p>The server is now running. It won't stop until you stop it (which you'll do in a moment).</p>
<h3>Testing the Server</h3>
<p>Open your browser and go to:</p>
<pre><code class="language-plaintext">http://localhost:3000
</code></pre>
<p>You'll see:</p>
<pre><code class="language-plaintext">Hello, World!
</code></pre>
<p>The server responded! You made a request, the server processed it, and sent back a response.</p>
<h3>Stopping the Server</h3>
<p>In the terminal, press <code>Ctrl + C</code>:</p>
<pre><code class="language-bash">^C
</code></pre>
<p>The server stops. You're back at the prompt.</p>
<h3>Breaking Down the Code</h3>
<pre><code class="language-javascript">const http = require("http");
</code></pre>
<p>This imports Node's built-in <code>http</code> module. It lets you create web servers.</p>
<pre><code class="language-javascript">const server = http.createServer((req, res) =&gt; {
  // This function runs every time a request comes in
});
</code></pre>
<p><code>createServer()</code> creates a server. The function (callback) runs for each request.</p>
<pre><code class="language-javascript">res.writeHead(200, { "Content-Type": "text/plain" });
</code></pre>
<p><code>writeHead()</code> sends the response header. <code>200</code> means "OK" (success). The second argument specifies the content type.</p>
<pre><code class="language-javascript">res.end("Hello, World!");
</code></pre>
<p><code>end()</code> sends the response body and closes the connection.</p>
<pre><code class="language-javascript">server.listen(3000);
</code></pre>
<p><code>listen()</code> makes the server listen on port 3000. Your browser connects to <code>localhost:3000</code>.</p>
<pre><code class="language-javascript">console.log("Server running on http://localhost:3000");
</code></pre>
<p>Print a message so you know the server started.</p>
<h3>Server with Different Paths</h3>
<p>Let's make a server that responds differently based on the URL path.</p>
<p>Create <code>server-routes.js</code>:</p>
<pre><code class="language-javascript">const http = require("http");

const server = http.createServer((req, res) =&gt; {
  if (req.url === "/") {
    res.writeHead(200);
    res.end("Home page");
  } else if (req.url === "/about") {
    res.writeHead(200);
    res.end("About page");
  } else if (req.url === "/contact") {
    res.writeHead(200);
    res.end("Contact page");
  } else {
    res.writeHead(404);
    res.end("Page not found");
  }
});

server.listen(3000);
console.log("Server running on http://localhost:3000");
</code></pre>
<p>Run it:</p>
<pre><code class="language-bash">node server-routes.js
</code></pre>
<p>Now try:</p>
<ul>
<li><code>http://localhost:3000/</code> → "Home page"</li>
<li><code>http://localhost:3000/about</code> → "About page"</li>
<li><code>http://localhost:3000/contact</code> → "Contact page"</li>
<li><code>http://localhost:3000/other</code> → "Page not found"</li>
</ul>
<p>Each path gives a different response.</p>
<h3>Server with HTML</h3>
<p>Let's send actual HTML instead of plain text.</p>
<p>Create <code>server-html.js</code>:</p>
<pre><code class="language-javascript">const http = require("http");

const server = http.createServer((req, res) =&gt; {
  res.writeHead(200, { "Content-Type": "text/html" });
  
  const html = `
    &lt;!DOCTYPE html&gt;
    &lt;html&gt;
    &lt;head&gt;
      &lt;title&gt;My Node Server&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
      &lt;h1&gt;Welcome to My Node Server&lt;/h1&gt;
      &lt;p&gt;This HTML is served from Node.js&lt;/p&gt;
    &lt;/body&gt;
    &lt;/html&gt;
  `;
  
  res.end(html);
});

server.listen(3000);
console.log("Server running on http://localhost:3000");
</code></pre>
<p>Run it:</p>
<pre><code class="language-bash">node server-html.js
</code></pre>
<p>Visit <code>http://localhost:3000</code> and you'll see a proper HTML page in your browser.</p>
<hr />
<h2>Project Structure</h2>
<p>As your projects grow, organize your files.</p>
<h3>Simple Structure</h3>
<pre><code class="language-plaintext">my-app/
  ├── server.js
  ├── helpers.js
  └── data.json
</code></pre>
<p>Everything in one folder.</p>
<h3>Better Structure</h3>
<pre><code class="language-plaintext">my-app/
  ├── src/
  │   ├── server.js
  │   ├── handlers.js
  │   └── utils.js
  ├── data/
  │   └── data.json
  ├── public/
  │   ├── style.css
  │   └── index.html
  └── package.json
</code></pre>
<p>Organized by purpose.</p>
<hr />
<h2>Node.js Execution Flow Diagram</h2>
<pre><code class="language-plaintext">Write Code
    ↓
hello.js file created
    ↓
terminal: node hello.js
    ↓
Node.js starts
    ↓
Read hello.js from disk
    ↓
Parse JavaScript
    ↓
Execute code
    ↓
    ├─ Variable declarations
    ├─ Function calls
    └─ I/O operations
    ↓
Output to terminal/console
    ↓
Script finishes
    ↓
Process exits
    ↓
Back to terminal prompt
</code></pre>
<hr />
<h2>Common Questions</h2>
<h3>Q: What's the difference between Node.js and npm?</h3>
<p><strong>Node.js</strong> is the JavaScript runtime.</p>
<p><strong>npm</strong> is the Node Package Manager. It lets you install libraries and tools.</p>
<pre><code class="language-bash">node --version    # Check Node.js
npm --version     # Check npm
</code></pre>
<h3>Q: Why does Node.js need a port number?</h3>
<p>Your computer can run multiple servers. Each server needs a unique port.</p>
<pre><code class="language-plaintext">Port 3000 → My app
Port 5000 → Another app
Port 8080 → Another app
</code></pre>
<p>A port is like an address on your computer.</p>
<h3>Q: Can I use Node.js with HTML/CSS?</h3>
<p>Yes. Node.js can serve HTML and CSS files. Or you can use frameworks like Express to make it easier.</p>
<h3>Q: Is Node.js used only for web servers?</h3>
<p>No. You can:</p>
<ul>
<li>Build web servers</li>
<li>Create command-line tools</li>
<li>Process files</li>
<li>Build real-time applications</li>
<li>Automate tasks</li>
<li>And much more</li>
</ul>
<h3>Q: Do I need a framework like Express?</h3>
<p>Not at all. You can build servers with just Node's built-in modules. But Express makes it easier.</p>
<h3>Q: Can I run Node.js code in the browser?</h3>
<p>No. Node.js runs on servers/your computer. Browser JavaScript is different. They have different APIs.</p>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Install Node.js and verify:</strong></p>
<pre><code class="language-bash">node --version
npm --version
</code></pre>
<p>Both should print version numbers.</p>
<p><strong>2. Try the REPL:</strong></p>
<pre><code class="language-bash">node
&gt; 5 + 5
&gt; "hello " + "world"
&gt; const name = "John"
&gt; name.toUpperCase()
&gt; .exit
</code></pre>
<p>Experiment with different JavaScript.</p>
<p><strong>3. Create your first script:</strong></p>
<p>Create <code>welcome.js</code>:</p>
<pre><code class="language-javascript">const name = "Your Name";
console.log("Welcome, " + name);
console.log("You are now a Node.js developer!");
</code></pre>
<p>Run it:</p>
<pre><code class="language-bash">node welcome.js
</code></pre>
<p><strong>4. Create a simple calculator:</strong></p>
<p>Create <code>calculator.js</code>:</p>
<pre><code class="language-javascript">function add(a, b) {
  return a + b;
}

function multiply(a, b) {
  return a * b;
}

// Your code: call these functions and print results
</code></pre>
<p><strong>5. Create a Hello World server:</strong></p>
<p>Create <code>server.js</code>:</p>
<pre><code class="language-javascript">const http = require("http");

const server = http.createServer((req, res) =&gt; {
  res.writeHead(200);
  res.end("Hello, World!");
});

server.listen(3000);
console.log("Server running on http://localhost:3000");
</code></pre>
<p>Run it and visit <code>http://localhost:3000</code> in your browser.</p>
<p><strong>6. Extend the server:</strong></p>
<p>Add more routes to your server:</p>
<ul>
<li><code>/</code> → "Home page"</li>
<li><code>/about</code> → "About page"</li>
<li><code>/contact</code> → "Contact page"</li>
<li>anything else → "Page not found"</li>
</ul>
<hr />
<h2>Common Mistakes</h2>
<h3>Mistake 1: Forgetting to Install Node.js</h3>
<pre><code class="language-plaintext">You: node hello.js
Terminal: command not found

Solution: Install Node.js from nodejs.org
</code></pre>
<h3>Mistake 2: Running a File That Doesn't Exist</h3>
<pre><code class="language-bash">node nonexistent.js
# Error: Cannot find module 'nonexistent.js'
</code></pre>
<p>Check the filename is correct and you're in the right folder.</p>
<h3>Mistake 3: Forgetting to Save the File</h3>
<pre><code class="language-javascript">// You write this in the editor
console.log("Hello");

// But don't save it
node hello.js
// Node runs the old version (or no file found)
</code></pre>
<p>Always save before running.</p>
<h3>Mistake 4: Not Stopping the Server Before Restarting</h3>
<pre><code class="language-bash">node server.js
# (ctrl + C to stop)

node server.js
# If you don't stop first:
# Error: Port 3000 already in use
</code></pre>
<p>Stop with <code>Ctrl + C</code> before running again.</p>
<h3>Mistake 5: Typos in require()</h3>
<pre><code class="language-javascript">const http = require("htttp");  // WRONG
const http = require("http");   // RIGHT
</code></pre>
<p>The module name is case-sensitive.</p>
<hr />
<h2>Next Steps</h2>
<p>You've learned the basics. Here's what to explore next:</p>
<h3>Learn More JavaScript</h3>
<ul>
<li>Variables and data types</li>
<li>Functions and callbacks</li>
<li>Objects and arrays</li>
<li>ES6+ features</li>
</ul>
<h3>Learn Node.js Modules</h3>
<ul>
<li><code>fs</code> module (file operations)</li>
<li><code>path</code> module (file paths)</li>
<li><code>events</code> module (event handling)</li>
<li><code>stream</code> module (data streaming)</li>
</ul>
<h3>Learn npm and Packages</h3>
<ul>
<li>Install packages: <code>npm install</code></li>
<li>Use package.json</li>
<li>Manage dependencies</li>
<li>Use popular packages</li>
</ul>
<h3>Learn a Framework</h3>
<ul>
<li><strong>Express.js</strong> - Web framework</li>
<li><strong>Fastify</strong> - Fast web framework</li>
<li><strong>Hapi</strong> - Full-featured framework</li>
</ul>
<h3>Build Projects</h3>
<ul>
<li>Web server</li>
<li>API</li>
<li>Command-line tool</li>
<li>Real-time application</li>
</ul>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Node.js</strong> is a JavaScript runtime for servers and computers.</p>
</li>
<li><p><strong>Installation</strong> is simple - download from nodejs.org and run the installer.</p>
</li>
<li><p><strong>REPL</strong> is an interactive JavaScript shell. Type <code>node</code> to start it.</p>
</li>
<li><p><strong>Scripts</strong> are JavaScript files you run with <code>node filename.js</code>.</p>
</li>
<li><p><strong>Server</strong> listens for requests and sends responses.</p>
</li>
<li><p><strong>Port 3000</strong> is a common port for development (<a href="http://localhost:3000">http://localhost:3000</a>).</p>
</li>
<li><p><strong>Ctrl + C</strong> stops a running script (like a server).</p>
</li>
<li><p><strong>File structure</strong> matters. Organize your code as projects grow.</p>
</li>
<li><p><strong>console.log()</strong> prints to the terminal.</p>
</li>
<li><p><strong>require()</strong> imports modules (like <code>http</code>).</p>
</li>
</ul>
<p>You now have Node.js running. You can execute JavaScript anywhere. The world of back-end development is open.</p>
<p>Build something! 🚀</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. 🔗 Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item><item><title><![CDATA[How Node.js Handles Multiple Requests with a Single Thread
]]></title><description><![CDATA[Node.js runs on a single thread. This seems impossible. How can one thread handle thousands of requests? The answer is the event loop and a clever design pattern. Understand this and Node.js's power b]]></description><link>https://blog.harshx.in/node-js-multiple-requests-in-single-thread</link><guid isPermaLink="true">https://blog.harshx.in/node-js-multiple-requests-in-single-thread</guid><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ChaiCode]]></category><category><![CDATA[Chaiaurcode]]></category><category><![CDATA[ChaiCohort]]></category><dc:creator><![CDATA[Harsh Raj]]></dc:creator><pubDate>Mon, 04 May 2026 07:36:07 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/695f2f2364e7902d8efbd627/ffe19ef3-a1b4-48c5-93c1-1298b7b617cc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Node.js runs on a single thread. This seems impossible. How can one thread handle thousands of requests? The answer is the event loop and a clever design pattern. Understand this and Node.js's power becomes obvious.</p>
<p>This is about how Node.js handles concurrency, the event loop, background workers, and why a single-threaded language can scale to handle massive workloads.</p>
<hr />
<h2>The Single-Threaded Nature of Node.js</h2>
<p>JavaScript code in Node.js runs on a single thread. Your application code executes one line at a time, in order.</p>
<h3>One Thread, One Stack, One Job at a Time</h3>
<pre><code class="language-plaintext">Your JavaScript Code
        ↓
Single Thread
        ↓
One statement at a time
        ↓
Next statement runs when previous finishes
</code></pre>
<pre><code class="language-javascript">console.log("1");
console.log("2");
console.log("3");

// Output:
// 1
// 2
// 3
</code></pre>
<p>The thread processes each line sequentially.</p>
<h3>Single-Threaded Means What, Exactly?</h3>
<pre><code class="language-javascript">function task1() {
  console.log("Task 1 starting");
  for (let i = 0; i &lt; 1000000000; i++) {} // Long operation
  console.log("Task 1 done");
}

function task2() {
  console.log("Task 2 starting");
  console.log("Task 2 done");
}

task1();
task2();

// Output:
// Task 1 starting
// Task 1 done
// Task 2 starting
// Task 2 done
</code></pre>
<p>Task 2 has to wait for Task 1 to finish. The single thread blocks. It can't do anything else until Task 1 completes.</p>
<p>This is a problem in a web server. If one request takes 10 seconds, all other requests wait 10 seconds.</p>
<h3>So How Does Node.js Handle Multiple Requests?</h3>
<p>The trick is: <strong>Node.js doesn't actually execute multiple JavaScript operations simultaneously.</strong> Instead, it cleverly switches between them using the event loop and delegates heavy work to background threads.</p>
<hr />
<h2>Understanding Concurrency vs Parallelism</h2>
<p>These terms sound similar but are fundamentally different.</p>
<h3>Parallelism: True Simultaneous Execution</h3>
<p>Multiple tasks run at the exact same time on different CPU cores.</p>
<pre><code class="language-plaintext">Core 1: Task A --------→
Core 2: Task B --------→
Core 3: Task C --------→

All three run simultaneously
</code></pre>
<p>Two multi-core processors can do parallel tasks. Node.js on a single thread cannot.</p>
<h3>Concurrency: Interleaved Execution</h3>
<p>One thread rapidly switches between tasks, making it appear like they run simultaneously.</p>
<pre><code class="language-plaintext">Thread:  Task A → Task B → Task A → Task C → Task B → Task C → ...

Switching so fast it looks like they're all running at once
</code></pre>
<p>Node.js does this. It's not true simultaneous execution, but it feels like it to the user.</p>
<h3>The Analogy: Chef Handling Orders</h3>
<p>Imagine a restaurant with one chef.</p>
<p><strong>Parallel:</strong> Multiple chefs cooking different dishes at the same time.</p>
<p><strong>Concurrent:</strong> One chef:</p>
<ol>
<li>Starts cooking an order (put it on the stove)</li>
<li>While it's cooking, takes the next order</li>
<li>While that's cooking, preps a third order</li>
<li>Checks on the first dish (it's done, plate it)</li>
<li>Gets the second dish, plates it</li>
<li>Continues cooking the third dish</li>
<li>Repeats</li>
</ol>
<p>The chef isn't cooking multiple dishes at once. But orders are being prepared concurrently. The chef switches between tasks during downtime.</p>
<p>Node.js is the chef. Your requests are orders. The event loop manages the switching.</p>
<hr />
<h2>The Event Loop: The Brain of Node.js</h2>
<p>The event loop is what makes concurrency possible. It's the mechanism that keeps Node.js running and switching between tasks.</p>
<h3>What Is the Event Loop?</h3>
<p>The event loop continuously checks for work to do. It runs through different types of tasks in a specific order.</p>
<pre><code class="language-plaintext">Event Loop Phases (simplified):

1. Timers → Execute setTimeout/setInterval callbacks
2. Pending I/O → Execute I/O operations
3. Check → Execute setImmediate callbacks
4. Close → Execute cleanup callbacks

When all phases are empty, loop repeats
</code></pre>
<h3>How It Works</h3>
<pre><code class="language-javascript">console.log("Start");

setTimeout(function() {
  console.log("After 0ms");
}, 0);

console.log("End");

// Output:
// Start
// End
// After 0ms
</code></pre>
<p>Here's what happens:</p>
<pre><code class="language-plaintext">1. console.log("Start") runs immediately
   Output: Start

2. setTimeout() registers the callback but doesn't execute it
   The callback is added to the event loop queue

3. console.log("End") runs immediately
   Output: End

4. The main JavaScript code is done

5. Event loop checks its queues
   It finds the setTimeout callback

6. Event loop executes the callback
   Output: After 0ms
</code></pre>
<p>The callback runs later, not immediately. The event loop scheduled it.</p>
<h3>Event Loop Keeps Running</h3>
<pre><code class="language-javascript">const http = require("http");

const server = http.createServer((req, res) =&gt; {
  res.writeHead(200);
  res.end("Hello");
});

server.listen(3000);

console.log("Server listening on port 3000");
</code></pre>
<p>Output: <code>Server listening on port 3000</code></p>
<p>Then the program doesn't exit. The server stays running. Why? The event loop is still running, waiting for requests. When a request comes in, it handles it. When done, it goes back to waiting.</p>
<p>The event loop never stops (until you kill the process).</p>
<h3>The Event Loop Executes Your Code</h3>
<pre><code class="language-plaintext">While (event loop is running) {
  if (timers have callbacks) {
    execute timer callbacks
  }
  
  if (I/O operations are done) {
    execute I/O callbacks
  }
  
  if (setImmediate has callbacks) {
    execute setImmediate callbacks
  }
  
  Wait for more events
}
</code></pre>
<p>This loop runs constantly, even when nothing is happening (it just waits).</p>
<hr />
<h2>Handling Multiple Requests with One Thread</h2>
<p>Now let's see how multiple HTTP requests are handled.</p>
<h3>Single-Threaded HTTP Server</h3>
<pre><code class="language-javascript">const http = require("http");

const server = http.createServer((req, res) =&gt; {
  console.log("Request received");
  
  // Simulate some work
  for (let i = 0; i &lt; 100000000; i++) {}
  
  res.writeHead(200);
  res.end("Hello");
});

server.listen(3000);
</code></pre>
<p>A request comes in. The callback runs. It does some work. It sends a response. Done.</p>
<p>But what if 5 requests come in simultaneously?</p>
<h3>Request 1 Timeline</h3>
<pre><code class="language-plaintext">Time: 0ms    → Request 1 arrives
Time: 0ms    → Callback runs
Time: 0-100ms → Doing work
Time: 100ms  → Response sent
</code></pre>
<h3>Requests 2-5 Arrive While Request 1 Is Processing</h3>
<pre><code class="language-plaintext">Time: 0ms    → Request 1 arrives → Callback queued
Time: 10ms   → Request 2 arrives → Queued
Time: 20ms   → Request 3 arrives → Queued
Time: 30ms   → Request 4 arrives → Queued
Time: 40ms   → Request 5 arrives → Queued

Time: 100ms  → Request 1 processing done → Response sent

Time: 100ms  → Request 2 callback runs
Time: 200ms  → Request 2 done → Response sent

Time: 200ms  → Request 3 callback runs
...and so on
</code></pre>
<p>Requests queue up. They're handled one at a time. This seems bad. But here's the trick: the waiting is hidden.</p>
<h3>The Real Trick: Non-Blocking I/O</h3>
<p>The problem above assumes blocking work (the for loop). In real applications, work is I/O (network, files, database):</p>
<pre><code class="language-javascript">const http = require("http");
const fs = require("fs");

const server = http.createServer((req, res) =&gt; {
  // Non-blocking I/O
  fs.readFile("data.txt", (err, data) =&gt; {
    res.writeHead(200);
    res.end(data);
  });
});

server.listen(3000);
</code></pre>
<p>This is what happens:</p>
<pre><code class="language-plaintext">Time: 0ms    → Request 1 arrives
Time: 0ms    → fs.readFile() called (non-blocking)
             → Callback registered in event loop
             → Function returns immediately

Time: 0ms    → Event loop is free!
             → Can handle Request 2

Time: 0ms    → Request 2 arrives
Time: 0ms    → fs.readFile() called (non-blocking)
             → Callback registered
             → Returns immediately

Time: 0ms    → Event loop is free!
             → Waiting for I/O to complete

Time: 50ms   → File read completes for Request 1
             → Callback for Request 1 executes
             → Response sent

Time: 50ms   → Event loop is free!
             → Waiting for Request 2's file read

Time: 100ms  → File read completes for Request 2
             → Callback for Request 2 executes
             → Response sent
</code></pre>
<p>Two requests are handled "concurrently" but with no blocking. While one is waiting for file I/O, the other can start.</p>
<hr />
<h2>Delegating Work to Background Threads</h2>
<p>Some work can't be non-blocking (CPU-intensive tasks). For this, Node.js uses the Worker Thread Pool.</p>
<h3>CPU-Intensive Work Blocks the Thread</h3>
<pre><code class="language-javascript">function expensiveCalculation() {
  let total = 0;
  for (let i = 0; i &lt; 10000000000; i++) {
    total += i;
  }
  return total;
}

const result = expensiveCalculation();
console.log(result);
</code></pre>
<p>This takes 10 seconds. During those 10 seconds, Node.js can't handle any requests. It's blocked.</p>
<h3>Delegating to Worker Threads</h3>
<p>Node.js has a Worker Thread Pool (libuv). You can delegate heavy work:</p>
<pre><code class="language-javascript">const { Worker } = require("worker_threads");
const http = require("http");

const server = http.createServer((req, res) =&gt; {
  // Delegate to a worker thread
  const worker = new Worker("./worker.js");
  
  worker.on("message", (result) =&gt; {
    res.writeHead(200);
    res.end("Result: " + result);
  });
});

server.listen(3000);
</code></pre>
<p>The worker thread does the heavy calculation in the background. The main thread remains free to handle other requests.</p>
<h3>What Gets Delegated?</h3>
<p>By default, Node.js delegates some I/O operations to the worker thread pool:</p>
<pre><code class="language-plaintext">File I/O (fs module)       → Worker threads
DNS lookups                → Worker threads
Some crypto operations     → Worker threads
Database connections       → Often delegated

Your JavaScript code       → Main thread
</code></pre>
<p>When you call <code>fs.readFile()</code>, it doesn't block the main thread. It's delegated to a worker thread. The worker reads the file. When done, the callback is queued in the event loop.</p>
<h3>libuv: The Magic Behind the Scenes</h3>
<p>libuv is a C library that Node.js uses. It manages:</p>
<ol>
<li>The event loop</li>
<li>The worker thread pool (usually 4 threads by default)</li>
<li>Platform-specific APIs for file I/O, networking, etc.</li>
</ol>
<pre><code class="language-plaintext">Node.js Application
        ↓
libuv (Event Loop + Thread Pool)
        ↓
Operating System APIs
        ↓
Hardware (CPU, Disk, Network)
</code></pre>
<hr />
<h2>The Complete Picture: How a Request Is Handled</h2>
<p>Let's trace a real HTTP request from start to finish.</p>
<h3>Request Handling Flow</h3>
<pre><code class="language-plaintext">1. Request arrives at the server
   ↓
2. Event loop detects it
   ↓
3. Callback function (request handler) queued
   ↓
4. Event loop executes the callback
   ↓
5. Callback calls fs.readFile() (or other I/O)
   ↓
6. fs.readFile() is delegated to worker thread
   Callback is registered
   ↓
7. Event loop is free, returns to waiting
   ↓
8. Worker thread reads file from disk
   ↓
9. File reading completes
   ↓
10. Callback is queued in event loop
    ↓
11. Event loop executes the callback
    ↓
12. Response is sent
    ↓
13. Connection closed
</code></pre>
<h3>Code Representation</h3>
<pre><code class="language-javascript">const http = require("http");
const fs = require("fs");

http.createServer((req, res) =&gt; {
  // Step 4: Callback runs
  console.log("Request received");
  
  // Step 5-6: Delegate file reading
  fs.readFile("data.txt", (err, data) =&gt; {
    // Step 11-12: Callback runs when file is read
    res.writeHead(200);
    res.end(data);
  });
  
  // Step 7: Function returns, thread is free
}).listen(3000);

// Step 1-2-3: Event loop waits for requests
</code></pre>
<h3>Multiple Requests Timeline</h3>
<pre><code class="language-plaintext">Request 1 arrives → Handler queued
Handler runs      → fs.readFile delegated to worker
                  → Handler returns (thread free)

Request 2 arrives → Handler queued
Handler runs      → fs.readFile delegated to worker
                  → Handler returns (thread free)

Request 3 arrives → Handler queued
Handler runs      → fs.readFile delegated to worker
                  → Handler returns (thread free)

(Meanwhile, workers are reading files)

Worker 1: File 1 done → Callback queued
Worker 2: File 2 done → Callback queued
Worker 3: File 3 done → Callback queued

Event loop: Execute callbacks
Callback 1 → Send Response 1
Callback 2 → Send Response 2
Callback 3 → Send Response 3
</code></pre>
<p>Three requests are handled concurrently. The main thread never blocks. Workers handle I/O in parallel.</p>
<hr />
<h2>Why Node.js Scales Well</h2>
<h3>Efficient Resource Usage</h3>
<p>Traditional servers create one thread per request:</p>
<pre><code class="language-plaintext">Request 1 → Thread 1 (dedicated)
Request 2 → Thread 2 (dedicated)
Request 3 → Thread 3 (dedicated)
...
Request 1000 → Thread 1000 (dedicated)

Memory usage: 1000 threads × memory per thread = a lot of memory
</code></pre>
<p>Node.js handles all requests with one thread:</p>
<pre><code class="language-plaintext">Request 1 → Event Loop
Request 2 → Event Loop
Request 3 → Event Loop
...
Request 1000 → Event Loop

Memory usage: 1 thread + small queues = much less memory
</code></pre>
<h3>Handling C10K Problem</h3>
<p>The C10K problem: How to handle 10,000 concurrent connections?</p>
<p>Traditional threaded servers struggle because:</p>
<ul>
<li>Creating 10,000 threads uses massive memory</li>
<li>Thread switching has overhead</li>
<li>Each thread has a stack (memory hungry)</li>
</ul>
<p>Node.js handles it elegantly:</p>
<ul>
<li>One thread handles all connections</li>
<li>I/O is delegated to worker threads</li>
<li>Connections are just data in memory (lightweight)</li>
</ul>
<h3>Event-Driven Architecture</h3>
<p>Node.js is event-driven:</p>
<pre><code class="language-plaintext">Something happens → Event fires → Callback runs
                    (non-blocking)
</code></pre>
<p>This is efficient. The thread doesn't wait for anything. It processes events as they arrive.</p>
<h3>Scales Horizontally</h3>
<p>For even better scaling, run multiple Node.js processes:</p>
<pre><code class="language-plaintext">Load Balancer
    ↓
├─ Node.js Process 1 (Single thread)
├─ Node.js Process 2 (Single thread)
├─ Node.js Process 3 (Single thread)
└─ Node.js Process 4 (Single thread)

Requests distributed across processes
Each process handles requests with its event loop
</code></pre>
<p>No threads to create. No memory overhead. Clean and fast.</p>
<hr />
<h2>Common Misconceptions</h2>
<h3>Misconception 1: "Node.js Runs Everything on One Thread"</h3>
<p><strong>False.</strong> JavaScript code runs on one thread. But I/O operations are delegated to worker threads. Crypto, DNS, and file operations use background threads.</p>
<h3>Misconception 2: "Node.js Can't Do Parallel Work"</h3>
<p><strong>False.</strong> The main thread can't run JavaScript in parallel. But libuv's worker thread pool runs I/O operations in parallel.</p>
<h3>Misconception 3: "Node.js Can't Handle CPU-Intensive Work"</h3>
<p><strong>True and false.</strong> Pure JavaScript running on the main thread blocks. But you can use Worker Threads to run CPU-intensive work in parallel:</p>
<pre><code class="language-javascript">const { Worker } = require("worker_threads");

const worker = new Worker("./heavy-calculation.js");

worker.on("message", (result) =&gt; {
  console.log("Result:", result);
});

// Main thread is free to handle other requests
</code></pre>
<h3>Misconception 4: "If One Request Takes 10 Seconds, All Requests Wait"</h3>
<p><strong>Only if the request does CPU-intensive work on the main thread.</strong> If it does I/O (file read, database query), other requests proceed while it waits.</p>
<hr />
<h2>Practical Example: Web Server</h2>
<h3>Simple Web Server Handling Multiple Requests</h3>
<pre><code class="language-javascript">const http = require("http");
const fs = require("fs");

const server = http.createServer((req, res) =&gt; {
  console.log("Request:", req.url);
  
  // Non-blocking file read
  fs.readFile("data.txt", (err, data) =&gt; {
    if (err) {
      res.writeHead(500);
      res.end("Error");
      return;
    }
    
    res.writeHead(200);
    res.end(data);
    console.log("Response sent for:", req.url);
  });
});

server.listen(3000);
console.log("Server listening on port 3000");
</code></pre>
<h3>What Happens</h3>
<ol>
<li><p>Request 1 arrives</p>
</li>
<li><p>Handler runs, calls fs.readFile()</p>
</li>
<li><p>fs.readFile() delegates to worker, returns immediately</p>
</li>
<li><p>Event loop is free</p>
</li>
<li><p>Request 2 arrives</p>
</li>
<li><p>Handler runs, calls fs.readFile()</p>
</li>
<li><p>fs.readFile() delegates to worker, returns immediately</p>
</li>
<li><p>Event loop is free</p>
</li>
<li><p>Workers finish reading files</p>
</li>
<li><p>Callbacks are queued</p>
</li>
<li><p>Event loop executes callbacks</p>
</li>
<li><p>Responses are sent</p>
</li>
</ol>
<p>All handled concurrently with one thread.</p>
<h3>Load Test</h3>
<pre><code class="language-bash">curl http://localhost:3000 &amp;
curl http://localhost:3000 &amp;
curl http://localhost:3000 &amp;
curl http://localhost:3000 &amp;
curl http://localhost:3000 &amp;
</code></pre>
<p>Send 5 requests at once. All handled concurrently. All respond quickly.</p>
<hr />
<h2>Event Loop Phases in Detail</h2>
<p>The event loop goes through phases:</p>
<h3>Phase 1: Timers</h3>
<p>Execute callbacks from <code>setTimeout()</code> and <code>setInterval()</code>.</p>
<pre><code class="language-javascript">setTimeout(() =&gt; {
  console.log("1 second passed");
}, 1000);
</code></pre>
<h3>Phase 2: I/O Callbacks</h3>
<p>Execute callbacks from file reads, network operations, etc.</p>
<pre><code class="language-javascript">fs.readFile("file.txt", (err, data) =&gt; {
  console.log("File read");
});
</code></pre>
<h3>Phase 3: Check</h3>
<p>Execute <code>setImmediate()</code> callbacks.</p>
<pre><code class="language-javascript">setImmediate(() =&gt; {
  console.log("Immediate");
});
</code></pre>
<h3>Phase 4: Close</h3>
<p>Execute close callbacks from streams and connections.</p>
<pre><code class="language-javascript">connection.on("close", () =&gt; {
  console.log("Connection closed");
});
</code></pre>
<p>The loop repeats these phases constantly.</p>
<h3>Order Matters</h3>
<pre><code class="language-javascript">setTimeout(() =&gt; console.log("timeout"), 0);
setImmediate(() =&gt; console.log("immediate"));
Promise.resolve().then(() =&gt; console.log("promise"));

// Output (usually):
// promise
// timeout
// immediate
</code></pre>
<p>Promises are microtasks (higher priority). They execute before the next phase.</p>
<hr />
<h2>Blocking vs Non-Blocking</h2>
<p>Understanding this distinction is crucial.</p>
<h3>Blocking: Stops the Event Loop</h3>
<pre><code class="language-javascript">const fs = require("fs");

// Blocking
const data = fs.readFileSync("file.txt");
console.log(data);

// The event loop is stopped until the file is read
</code></pre>
<p>Don't use <code>Sync</code> methods in production. They block.</p>
<h3>Non-Blocking: Frees the Event Loop</h3>
<pre><code class="language-javascript">const fs = require("fs");

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

console.log("This runs before the file is read");
</code></pre>
<p>The callback happens later. The event loop continues.</p>
<h3>Why Non-Blocking Matters</h3>
<p>With blocking:</p>
<pre><code class="language-plaintext">Request 1 arrives
File read (BLOCKS for 100ms)
Request 2 arrives (waits)
Request 3 arrives (waits)
File read done
Response 1 sent
Request 2 handled (BLOCKS for 100ms)
...all requests delayed
</code></pre>
<p>With non-blocking:</p>
<pre><code class="language-plaintext">Request 1 arrives
File read starts (non-blocking)
Request 2 arrives
File read starts (non-blocking)
Request 3 arrives
File read starts (non-blocking)
Files read (in parallel)
All responses sent
Total time: ~100ms instead of 300ms
</code></pre>
<hr />
<h2>Practice Assignment</h2>
<p><strong>1. Understand the event loop:</strong></p>
<pre><code class="language-javascript">console.log("1");

setTimeout(() =&gt; {
  console.log("2");
}, 0);

console.log("3");

// What will the output be? Why?
</code></pre>
<p><strong>2. Non-blocking file operations:</strong></p>
<pre><code class="language-javascript">const fs = require("fs");

// Write code that:
// 1. Reads 3 files without blocking
// 2. Prints them all when done

fs.readFile("file1.txt", (err, data) =&gt; {
  // Your code
});

// ... more files
</code></pre>
<p><strong>3. Handle multiple HTTP requests:</strong></p>
<pre><code class="language-javascript">const http = require("http");
const fs = require("fs");

// Create a server that:
// 1. Reads a file for each request
// 2. Sends it as response
// 3. Handles multiple requests concurrently

// Send 5 requests: curl http://localhost:3000 &amp;
</code></pre>
<p><strong>4. Identify blocking code:</strong></p>
<pre><code class="language-javascript">// Which of these is blocking?

// A:
const data = fs.readFileSync("file.txt");

// B:
fs.readFile("file.txt", callback);

// C:
const result = expensiveCalculation();

// D:
setTimeout(callback, 0);
</code></pre>
<p><strong>5. Event loop phases:</strong></p>
<pre><code class="language-javascript">setTimeout(() =&gt; console.log("A"), 0);
setImmediate(() =&gt; console.log("B"));
process.nextTick(() =&gt; console.log("C"));

// What order will they print?
</code></pre>
<hr />
<h2>Common Mistakes</h2>
<h3>Mistake 1: Using Blocking Operations</h3>
<pre><code class="language-javascript">// WRONG - blocks the event loop
const data = fs.readFileSync("file.txt");
res.end(data);

// RIGHT - non-blocking
fs.readFile("file.txt", (err, data) =&gt; {
  res.end(data);
});
</code></pre>
<h3>Mistake 2: Long-Running Synchronous Code</h3>
<pre><code class="language-javascript">// WRONG - blocks for 5 seconds
for (let i = 0; i &lt; 10000000000; i++) {}
res.end("Done");

// RIGHT - delegate to worker thread or break into chunks
</code></pre>
<h3>Mistake 3: Misunderstanding Callback Timing</h3>
<pre><code class="language-javascript">// WRONG - expecting callback to run immediately
let data;

fs.readFile("file.txt", (err, contents) =&gt; {
  data = contents;
});

console.log(data); // undefined - callback hasn't run yet!
</code></pre>
<h3>Mistake 4: Not Handling Errors in Callbacks</h3>
<pre><code class="language-javascript">// WRONG - ignoring errors
fs.readFile("file.txt", (err, data) =&gt; {
  console.log(data); // Crashes if error and data is undefined
});

// RIGHT - check for errors
fs.readFile("file.txt", (err, data) =&gt; {
  if (err) {
    console.error(err);
    return;
  }
  console.log(data);
});
</code></pre>
<h3>Mistake 5: Assuming One Request Blocks Others</h3>
<pre><code class="language-javascript">// WRONG - thinking this blocks other requests
app.get("/slow", (req, res) =&gt; {
  fs.readFile("large-file.txt", (err, data) =&gt; {
    // While waiting here, other requests ARE handled
    res.end(data);
  });
});

// It doesn't block! Other requests proceed while this waits.
</code></pre>
<hr />
<h2>Quick Recap</h2>
<ul>
<li><p><strong>Node.js runs JavaScript on a single thread.</strong> Your code executes sequentially, one statement at a time.</p>
</li>
<li><p><strong>The event loop</strong> is what makes concurrency possible. It continuously checks for work and executes callbacks.</p>
</li>
<li><p><strong>I/O is non-blocking.</strong> When you read a file or query a database, it's delegated to a worker thread. The main thread continues.</p>
</li>
<li><p><strong>Concurrency vs Parallelism:</strong></p>
<ul>
<li>Concurrency: One thread switches between tasks</li>
<li>Parallelism: Multiple threads run simultaneously</li>
<li>Node.js is concurrent (one thread) but uses parallelism for I/O</li>
</ul>
</li>
<li><p><strong>The worker thread pool</strong> (libuv) handles:</p>
<ul>
<li>File I/O</li>
<li>DNS lookups</li>
<li>Some crypto operations</li>
<li>System-level I/O</li>
</ul>
</li>
<li><p><strong>Multiple requests are handled concurrently</strong> because:</p>
<ul>
<li>The main thread isn't blocked</li>
<li>I/O operations happen in the background</li>
<li>Callbacks are queued and executed when ready</li>
</ul>
</li>
<li><p><strong>Node.js scales well because:</strong></p>
<ul>
<li>One thread uses less memory than many threads</li>
<li>I/O is efficient (parallel in background)</li>
<li>No thread creation overhead</li>
<li>Can handle thousands of concurrent connections</li>
</ul>
</li>
<li><p><strong>Never block the event loop:</strong></p>
<ul>
<li>Use non-blocking I/O (fs.readFile, not fs.readFileSync)</li>
<li>Avoid long CPU-intensive synchronous code</li>
<li>Use Worker Threads for heavy computation</li>
</ul>
</li>
<li><p><strong>The event loop has phases:</strong> Timers → I/O → Check → Close → Repeat</p>
</li>
<li><p><strong>For true parallelism,</strong> use Worker Threads or run multiple Node.js processes.</p>
</li>
</ul>
<p>Master the event loop and concurrency model, and you'll write scalable, efficient Node.js applications.</p>
<p>Happy coding! 🚀</p>
<hr />
<blockquote>
<p>If you enjoyed this article, check out my other blogs on this profile. 🔗 Connect with me: <a href="https://linkedin.com/in/rajharsh03">LinkedIn</a> | <a href="https://github.com/RajHarsh03">GitHub</a> | <a href="https://x.com/rajharsh03">X (Twitter)</a></p>
</blockquote>
]]></content:encoded></item></channel></rss>