JavaScript outside the browser
For years, JavaScript only lived inside the browser. Node.js changed that: it is a runtime environment that lets you run JavaScript on your machine or on a server, just as you would run Python or Java.
Under the hood, Node uses V8, the same JavaScript engine as Chrome. V8 compiles your code to very fast machine instructions. V8 lacks everything that is not the language itself (reading files, opening network connections...): that is provided by Node, which adds its own set of APIs.
The browser is not here
Since there is no browser, there is no window, no document and no DOM. In their
place, Node offers its own global objects:
console.log(process.version); // Node version, e.g. "v20.11.0"
console.log(process.platform); // "linux", "darwin", "win32"...
globalThis.myData = 42; // 'global' / 'globalThis' instead of 'window'
process: process information and control (arguments, environment variables, exit...).global/globalThis: the global object (the equivalent ofwindow).
The non-blocking model
Node runs your JavaScript on a single thread. This sounds limiting, but it is the key to its performance thanks to one detail: I/O is asynchronous.
When you request something slow (reading a file, a database query, a network request), Node does not wait around (it does not block the thread): it delegates that operation, keeps handling other things and, when the result is ready, runs your continuation code. That mechanism is the event loop: a loop that pulls finished tasks from a queue and runs their callbacks.
console.log("1: start");
setTimeout(() => console.log("3: deferred task"), 0);
console.log("2: keep going without waiting");
// Prints: 1, 2, 3 -> the setTimeout does not block; it runs "later"
That is why a single Node server can handle thousands of connections at once: while one waits on the disk or the network, the thread is free to serve the others. The golden rule: never block the event loop with heavy synchronous work, or every request will freeze.
Examples
The event loop does not wait: the order is not the code's order
console.log("A");
setTimeout(() => console.log("C (deferred)"), 0);
Promise.resolve().then(() => console.log("B (microtask)"));
console.log("D");
// Order: A, D, B, C