What is Node.js? Runtime, V8 & Architecture

๐ŸŸข Node.js LTS ๐Ÿ“— Chapter 1 of 49 ๐Ÿ“‚ Phase 1: Node.js Introduction ๐Ÿ—“๏ธ 2026 Edition
๐Ÿ“Œ Covered in this chapter: What is Node.js? ยท Node.js vs Browser JS ยท Event Loop & Non-Blocking I/O ยท Features & Use Cases ยท Limitations ยท V8 & libuv Architecture

Deep-dive introduction to Node.js: history by Ryan Dahl, the V8 engine and libuv, event-driven non-blocking I/O, Node.js vs browser JavaScript, real-world use cases, limitations, and exactly how Node.js executes your code under the hood.

1What is Node.js? Origins, V8 Engine & Why It Was Created

Node.js is a free, open-source, cross-platform JavaScript runtime environment that lets you execute JavaScript code outside of a web browser. It was created in 2009 by Ryan Dahl, who wanted to build web servers capable of handling thousands of concurrent connections without the heavy memory overhead of one-thread-per-request models used by older servers like Apache.

Node.js is built on Google Chrome's open-source V8 JavaScript Engine โ€” the same high-performance engine that powers the Chrome browser. V8 compiles JavaScript directly to native machine code before executing it, which makes Node.js extremely fast for I/O-heavy workloads. Around this V8 core, Node.js adds its own C++ bindings and a library called libuv, which provides the event loop, thread pool, and non-blocking I/O operations (file access, networking, DNS, timers).

Why Node.js Was a Big Deal:

  • One language, both sides: The same JavaScript you already know from the browser can now run your backend server, CLI tools, and build scripts.
  • Non-blocking by default: Node.js handles thousands of simultaneous connections on a single thread using asynchronous, event-driven I/O.
  • npm ecosystem: Node.js ships with npm, the largest software package registry in the world, giving instant access to millions of reusable packages.
  • Backed by the OpenJS Foundation: Node.js is maintained by a large open-source community and used in production by Netflix, LinkedIn, PayPal, Uber, and NASA.
๐Ÿ’ป Example 1: Checking Your Node.js Version
// Run this in your terminal, not inside a .js file
node --version
// Example output: v22.11.0
๐Ÿ” Line-by-Line Code Breakdown:
  • node --version: Asks the globally installed Node.js binary to print its own version number.
  • The v22.11.0 output confirms Node.js is installed correctly and shows which major version you're running (important, since APIs change between major versions).
2Node.js vs Browser JavaScript โ€” Key Differences

JavaScript in the browser and JavaScript in Node.js share the exact same language (syntax, variables, functions, promises) because both are powered by the V8 engine. The difference is the environment around the language โ€” the set of built-in objects and APIs each platform exposes.

In the browser, JavaScript has access to the DOM (document, window) to manipulate web pages. Node.js has no browser, no DOM, and no window object โ€” instead, it exposes APIs for interacting with the operating system: the file system, network sockets, processes, and environment variables.

AspectBrowser JavaScriptNode.js
Global objectwindowglobal / globalThis
DOM accessYes (document, elements)No DOM at all
File system accessNot allowed (sandboxed)Full access via node:fs
Module systemES Modules (<script type="module">)CommonJS + ES Modules
Networkingfetch(), XHR (client only)node:http โ€” can act as client and server
Typical useUI interactivity, DOM updatesServers, APIs, CLIs, build tools
๐Ÿ’ป Example 2: A Line That Only Works in Node.js
JavaScript (Node.js) โ–ถ Run in Compiler
// node:process is a Node-only global โ€” the browser has no equivalent
console.log("Running on Node.js version:", process.version);
console.log("Current working directory:", process.cwd());
๐Ÿ” Line-by-Line Code Breakdown:
  • process: A global object available only in Node.js, giving information about โ€” and control over โ€” the current running program.
  • process.version: Returns the exact Node.js version string powering this script.
  • process.cwd(): Returns the absolute path of the directory the script was launched from.
3Runtime Environment, Event-Driven Architecture & Non-Blocking I/O

A runtime environment is the software that provides everything a program needs to execute: memory management, a way to run instructions, and access to system resources. Node.js is JavaScript's runtime outside the browser โ€” it takes your .js file, hands it to V8 for execution, and wires up libuv underneath to talk to the operating system.

Node.js follows an event-driven, non-blocking I/O model. Instead of waiting (blocking) while a slow operation like reading a file or querying a database finishes, Node.js registers a callback function and immediately moves on to the next task. When the slow operation completes, Node's event loop picks up the result and runs your callback โ€” all on a single main thread.

Why this matters: A traditional blocking server might spawn one OS thread per client connection, which becomes expensive at scale. Node.js instead uses one event loop thread to juggle thousands of pending I/O operations concurrently, making it extremely efficient for network-heavy applications like APIs, chat servers, and streaming services.
๐Ÿ’ป Example 3: Blocking vs Non-Blocking Behavior
JavaScript (Node.js) โ–ถ Run in Compiler
console.log("1. Script starts");

// setTimeout is non-blocking โ€” Node registers it and moves on immediately
setTimeout(() => {
  console.log("3. This runs later, after the main script finishes");
}, 0);

console.log("2. Script continues without waiting");
๐Ÿ” Line-by-Line Code Breakdown:
  • console.log("1. ..."): Executes immediately, synchronously.
  • setTimeout(callback, 0): Even with a 0ms delay, Node hands this callback to libuv's timer queue and does not wait for it.
  • console.log("2. ..."): Runs right after, before the timeout callback, because the main script must finish first.
  • Only once the call stack is empty does the event loop run the queued timeout callback, printing line 3 last.
Expected Output: 1. Script starts โ†’ 2. Script continues without waiting โ†’ 3. This runs later...
4Features, Real-World Use Cases & the npm Ecosystem

Node.js is a general-purpose runtime, but its architecture makes it especially strong at specific kinds of work. Here's what it's commonly used for in production:

  • REST & GraphQL APIs โ€” backend services for web and mobile apps, typically built with Express.js or Fastify.
  • Real-time applications โ€” chat apps, live dashboards, and multiplayer features using WebSockets or Socket.IO.
  • Microservices โ€” small, independently deployable services that communicate over HTTP or message queues.
  • Command-line tools โ€” popular CLIs like npm itself, the Angular CLI, and Create React App are all built with Node.js.
  • Build tooling โ€” bundlers like Webpack, Vite, and esbuild run on Node.js under the hood.
  • Streaming services โ€” Node's stream APIs make it well suited for proxying and processing large amounts of data efficiently.

Node.js ships with npm (Node Package Manager) by default โ€” the world's largest software registry, with well over 2 million published packages covering everything from HTTP frameworks to date formatting utilities.

๐Ÿ’ป Example 4: Checking npm and Installing a Package
npm --version
npm init -y
npm install express
๐Ÿ” Line-by-Line Code Breakdown:
  • npm --version: Confirms npm ships alongside your Node.js installation.
  • npm init -y: Generates a default package.json file that describes your project and its dependencies.
  • npm install express: Downloads the Express.js framework into a local node_modules folder and records it as a dependency.
5Where NOT to Use Node.js โ€” Limitations & CPU-Bound Work

Node.js excels at I/O-bound work, but it is single-threaded for JavaScript execution. That means any long-running, CPU-intensive synchronous code (heavy image processing, complex calculations, large in-memory sorting) will block the single event loop thread โ€” freezing every other request your server is handling until that computation finishes.

Rule of thumb: if a task is mostly "waiting" (for a database, a file, or a network response), Node.js handles it beautifully. If a task is mostly "computing" (video encoding, machine learning inference, cryptographic hashing at scale), consider offloading it to node:worker_threads, a child process, or a different language/service entirely.

Common Limitations to Keep in Mind:

  • CPU-bound tasks block the event loop and degrade performance for all connected clients.
  • Callback complexity โ€” deeply nested callbacks ("callback hell") can hurt readability if Promises/async-await aren't used consistently.
  • Immature ORMs (historically) โ€” improving fast, but some database tooling is younger than equivalents in Java or Python.
  • Single-threaded by default โ€” to use multiple CPU cores you must explicitly use the cluster module or worker threads.
๐Ÿ’ป Example 5: A Blocking Loop Freezing the Event Loop
JavaScript (Node.js) โ–ถ Run in Compiler
console.log("Server received request A");

// A heavy synchronous loop โ€” this blocks EVERYTHING until it finishes
let total = 0;
for (let i = 0; i < 5_000_000_000; i++) {
  total += i;
}

console.log("Finished heavy computation:", total);
console.log("Only now can Server receive request B");
๐Ÿ” Line-by-Line Code Breakdown:
  • The synchronous for loop runs entirely on the main thread with no yielding.
  • While it runs, Node.js cannot process any other incoming requests, timers, or I/O callbacks โ€” everything queues up behind it.
  • This is the single most common Node.js production mistake: putting heavy synchronous computation directly inside a request handler.
6How Node.js Executes Code Under the Hood (V8 + libuv Architecture)

Understanding Node's internal architecture helps explain why it behaves the way it does. Node.js is composed of three main layers working together:

  • V8 Engine: Parses and compiles your JavaScript into optimized machine code, and manages the JavaScript heap and garbage collection.
  • libuv: A C library that provides the event loop, a thread pool for expensive operations (like file system access and DNS lookups), and cross-platform abstractions over the OS's async I/O primitives (epoll on Linux, kqueue on macOS, IOCP on Windows).
  • Node.js Bindings & Core Modules: C++ bindings connect V8's JavaScript world to libuv's system-level world, exposing it all through familiar JavaScript APIs like fs, http, and net.

When your script calls an async function such as fs.readFile(), Node hands the actual file-reading work off to libuv's thread pool (or the OS kernel directly for networking), and immediately continues executing the rest of your script. The event loop continuously checks whether any pending operations have completed; once one finishes, its callback is pushed onto the call stack to run.

๐Ÿ’ป Example 6: Reading a File Asynchronously
JavaScript (Node.js) โ–ถ Run in Compiler
import { readFile } from "node:fs";

console.log("Start reading file...");

readFile("package.json", "utf8", (error, data) => {
  if (error) {
    console.error("Error:", error.message);
    return;
  }
  console.log("File contents loaded:", data.length, "characters");
});

console.log("This line runs before the file finishes loading");
๐Ÿ” Line-by-Line Code Breakdown:
  • import { readFile }: Imports the async, callback-based file reading function from Node's built-in node:fs module.
  • readFile(path, encoding, callback): Hands the actual disk read to libuv's thread pool and returns immediately โ€” it does not block.
  • The final console.log runs before the file finishes loading, proving the call is non-blocking.
  • Once libuv finishes reading the file, the event loop schedules the callback, which then logs the file's length.
โ“ Frequently Asked Questions (FAQ)

Q Is Node.js a programming language?

No. Node.js is a JavaScript runtime environment, not a language. The language is JavaScript; Node.js is the engine (V8) plus system-level APIs (libuv) that let that JavaScript run outside a browser.

Q Is Node.js single-threaded or multi-threaded?

Node.js executes your JavaScript on a single main thread, but libuv maintains a background thread pool for certain operations (like file I/O and DNS lookups), and you can spin up additional threads explicitly using the worker_threads module or the cluster module.

Q Can Node.js be used for the frontend?

Node.js itself runs on the server or command line, not inside a browser page. However, it's essential to frontend development anyway โ€” tools like Webpack, Vite, Babel, and npm all run on Node.js to build the JavaScript that eventually ships to the browser.

OC
Written by Our Compiler Technical Editorial Team
Reviewed for accuracy & tested on Node.js LTS ยท Last updated August 2026