This is the heart of Node.js 🚀. Let’s go step by step.


🧵 1. Single-threaded

  • Node.js executes JavaScript code on a single thread (main thread).

  • That means there is one call stack handling all JS instructions.

  • Unlike languages like Java or C#, Node does not spin up multiple threads to handle each request.

👉 Why this matters:

  • You don’t need to worry about thread synchronization or race conditions in typical JS code.

  • But it also means blocking operations (like heavy CPU work or synchronous I/O) can freeze the entire app.


⚡ 2. Event-driven

  • Instead of waiting for tasks to finish, Node.js reacts to events.

  • Example: When a file finishes reading, Node emits an event — and your callback (or promise/async function) runs.

  • At the center of this is the event loop, which continuously checks:

    • “Do we have new events/callbacks to process?”

    • “Do we have completed I/O tasks ready to handle?”

👉 This is why Node can handle thousands of requests on one thread.


🔄 3. Asynchronous by default

  • Most Node APIs are non-blocking: they start a task and immediately return control to the main thread.

  • The actual work (like reading a file, making a network request, querying a DB) happens in the background.

  • When it’s done, the callback/promise is pushed back into the event loop.

Example:

const fs = require("fs");
 
// Non-blocking (async)
fs.readFile("data.txt", "utf8", (err, data) => {
  if (err) throw err;
  console.log("File content:", data);
});
 
console.log("Reading file...");

Output:

Reading file...
File content: <data here>

👉 The program doesn’t “pause” at readFile — it continues immediately.


📊 Putting it Together

  • Single-threaded: One main JS thread handles the code.

  • Event-driven: The event loop decides what happens when tasks complete.

  • Async by default: Long operations don’t block; they notify the loop when done.

This design makes Node.js:

  • 🟢 Great for I/O-heavy apps (APIs, real-time chat, streaming).

  • 🔴 Not ideal for CPU-heavy tasks (image processing, big computations).


In short: Node.js runs one main thread, uses an event loop to handle callbacks/events, and relies on async I/O to stay responsive.