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.