Node.js 2,131 is an asynchronous, event-driven JavaScript runtime for building scalable network applications. The official description repays a literal reading: "almost no function in Node.js directly performs I/O, so the process never blocks except when the I/O is performed using synchronous methods."
Your code runs on one thread; when it asks for a file, a DNS record or a database row, the request goes to the operating system and the thread moves on. No thread and no stack per connection is exactly what a chat server or a server-rendered React 7,897 app needs. The price is a shared thread: a 200 ms password hash, a synchronous read of a 50 MB log, or a backtracking regular expression freezes every other request in the process. Processes and Clustering moves such work off it.
import { readFile } from 'node:fs/promises';
const t0 = performance.now();
const at = (s) => console.log(`${s.padEnd(18)} ${(performance.now() - t0).toFixed(1)} ms`);
readFile(new URL(import.meta.url)).then(() => at('file read done'));
setTimeout(() => at('timer fired'), 50);
Promise.resolve().then(() => at('microtask'));
at('top-level code');top-level code 0.8 ms microtask 3.2 ms file read done 4.1 ms timer fired 51.2 ms
The script body runs to completion first. Only then does Node drain the microtask queue, and only then does it wait for I/O — which is why the promise callback jumps ahead of a file read that started earlier.
Node runs in more places than "on the server": command-line tools, bundlers, Electron 20,509 applications and serverless functions. Several edge platforms implement only part of the Node API on a different engine, so code written against web-standard globals — fetch, ReadableStream, crypto.subtle — travels further than code built on node: modules, a choice that returns in Next.js.