Skip to content
Node.js introduction 2 min read

What is Node.js?

Node.js is a JavaScript runtime that lets you run JavaScript outside the browser—on servers, command-line tools, build pipelines, and more. It was created by Ryan Dahl in 2009 to make scalable network applications easy to build without managing threads by hand.

A runtime, not a framework

Node.js is not a language and not a web framework. It is the environment that executes your JavaScript. It bundles Google’s V8 engine to compile and run code, plus a set of native C++ libraries that expose the file system, network sockets, cryptography, and the operating system to your scripts.

Node.js gives JavaScript everything the browser deliberately withholds: file access, raw TCP, child processes, and direct OS calls.

V8 and libuv

Two components do the heavy lifting:

ComponentRole
V8Compiles JavaScript to optimized machine code (the same engine in Chrome).
libuvA C library providing the event loop, thread pool, and async I/O across platforms.

V8 runs your JavaScript fast. libuv handles the slow parts—disk reads, DNS lookups, network requests—off the main thread and notifies V8 when results are ready. This division is the foundation of Node’s concurrency model.

The non-blocking, single-threaded model

Your JavaScript runs on a single thread. There is one call stack executing one thing at a time. This sounds limiting, but Node never blocks that thread waiting on I/O. Instead, it hands slow operations to libuv and registers a callback to run when they complete.

const fs = require("fs");

console.log("1: start");

fs.readFile("./data.txt", "utf8", (err, data) => {
  console.log("3: file read finished");
});

console.log("2: end");

Output:

1: start
2: end
3: file read finished

The file read is dispatched and the thread immediately continues. The callback fires later, once the data is available. While that read is pending, your application can handle thousands of other connections. This is why Node excels at I/O-heavy workloads: it spends its single thread orchestrating work rather than waiting.

CPU-bound tasks (image processing, heavy crypto, large loops) do block the thread. For those, use Worker Threads or offload to a separate service.

Where Node.js shines

  • REST and GraphQL APIs — high-throughput JSON services.
  • Real-time apps — chat, collaboration, and gaming via WebSockets.
  • Streaming — process data as it arrives without buffering everything.
  • Microservices — small, fast-starting processes.
  • Tooling — bundlers, linters, and CLIs (npm, Vite, ESLint all run on Node).

It is less suited to CPU-bound number crunching, where a multi-threaded runtime may serve you better.

A five-line HTTP server

You can serve HTTP with nothing but the standard library:

const http = require("http");

http
  .createServer((req, res) => res.end("Hello from Node.js"))
  .listen(3000, () => console.log("Listening on http://localhost:3000"));

Run it with node server.js and open the URL. No framework, no dependencies—just the runtime. From here, the rest of this guide builds toward modules, the event loop, async patterns, and production-grade APIs.

Last updated June 1, 2026
Was this helpful?