Question presented to candidate: "Draw or describe the pieces that make up a running Node.js process, from your JavaScript code down to the operating system. What actually talks to what?"
What a strong answer should cover:
- Node's architecture is a layered stack, not one undifferentiated "runtime": your JavaScript code runs on V8 (parsing, JIT-compiling, executing — covered in its own dedicated question), which is embedded inside Node alongside libuv (the event loop, thread pool, and cross-platform async I/O — covered in its own dedicated question), connected by a layer of C++ bindings that expose native functionality (the file system, networking, process control) to JavaScript.
- 📌 Verified, not assumed: V8 and libuv are two separate, independently versioned embedded components — confirmed directly via
process.versions.v8andprocess.versions.uv, each reporting its own distinct version number bundled with the same Node release, not one combined "Node version." - Node's standard library (
fs,http,net,crypto, and others) is the JavaScript-facing API built on top of those C++ bindings — application code almost never touches the C++ layer directly; it calls the JavaScript standard library, which calls into C++, which calls into libuv/V8/the OS as appropriate. - The event loop (libuv's own loop, exposed to JavaScript scheduling — covered fully in its own dedicated question) is the mechanism tying this together at runtime: JavaScript callbacks are invoked by the event loop as libuv's phases advance, in response to I/O completion, timers, or thread-pool task completion.
- A precise answer names the request flow through these layers concretely: application JS calls a standard-library function (e.g.
fs.readFile) → that calls into a C++ binding → the binding dispatches to libuv (the thread pool, for file I/O) → libuv notifies the event loop on completion → the event loop invokes the original JavaScript callback — a full round trip through every layer, not just "Node reads a file." - A precise answer also names what changed over time worth being aware of, without overclaiming specifics: Node has migrated some internal binding mechanisics (e.g. history around N-API for native addon stability) — the broad layered structure (JS → C++ bindings → libuv/V8 → OS) has remained stable even as specific internal implementation details have evolved across releases.
Clarifying questions expected:
- "Does the interviewer want the high-level layer diagram, or a specific request's full round trip through those layers?" — both are reasonable answers to "describe the architecture," at different depths.
- "Is Node's standard library itself part of what should be described, or just the lower-level runtime components (V8, libuv)?"
Code / implementation expected: Optional — confirming V8 and libuv's distinct, independently-reported version numbers via process.versions is a small, concrete way to demonstrate the "separate components" claim rather than assert it.