Knowing what Node is (and isn't) tells you what code will run in it and why its I/O model looks the way it does.
Node.js is a JavaScript runtime: it takes Google's V8 engine (the same one in Chrome) and wraps it in a C++ program that adds what a browser doesn't give you — reading files, opening sockets, spawning processes, reading environment variables. That glue is mostly provided by libuv, a library that handles asynchronous I/O and the event loop.
The language is the same JavaScript you know. What changes is the environment:
- There is no
window, nodocument, no DOM. Instead you getprocess,Buffer, and built-in modules such asnode:fs,node:httpandnode:path. - Many web APIs exist anyway:
fetch,URL,AbortController,setTimeout,structuredClone,TextEncoder,crypto.randomUUID(), web streams andWebSocketare all global. - Your program is a long-lived process you control, not a page the user opens.
Node's defining design choice is non-blocking I/O on a single JavaScript thread. When you read a file or wait for an HTTP response, Node hands the work to the operating system (or libuv's thread pool) and keeps running other JavaScript. When the result is ready, your callback or await resumes. One process can therefore juggle thousands of concurrent connections without a thread per request — which is why Node is popular for web servers, APIs, CLIs, build tools and real-time apps.
The flip side: CPU-heavy JavaScript blocks everything else on that thread. Node is great at waiting on many things at once, less so at crunching numbers in JS (workers help there).
This course targets Node.js 22 LTS. Even-numbered releases become Long-Term Support and are what you should run in production; check yours with node --version.
Example
// hello.js — run with: node hello.js
console.log(`Node ${process.version} on ${process.platform}`);
console.log(typeof window); // 'undefined' — no browser globals
console.log(typeof fetch); // 'function' — web APIs are available
// Non-blocking: the timer callback runs later; the next line runs first
setTimeout(() => console.log("timer fired"), 0);
console.log("end of script");
// Output order: Node v22..., undefined, function, end of script, timer firedRemember
- Node = V8 + libuv + built-in modules, no DOM
- I/O is non-blocking; one JS thread serves many concurrent operations
- CPU-heavy JavaScript blocks everything on that thread
- Use an even-numbered LTS release (22) in production
Watch out for
- Expecting browser objects like
windowordocumentto exist.