Runtime · V8 · Non-blocking I/O

Node.js Server

An event-driven JavaScript runtime built on Chrome’s V8 engine. One language across the stack, an asynchronous core, and the largest package ecosystem in software.

Get Started API Docs

Non-blocking I/O

A single-threaded event loop offloads file, network, and timer work so thousands of connections stay responsive.

npm ecosystem

Over two million packages. Reach for a tested library instead of reinventing infrastructure.

One language

JavaScript and TypeScript from browser to API to build scripts. Shared models, shared validation.

Streaming & real-time

First-class streams and WebSocket support make chat, live feeds, and proxies natural to build.

Built-in tooling

A test runner, watch mode, permission model, and .env loader now ship with the runtime — fewer dependencies to wire up.

Runs everywhere

The same binary runs on Linux, macOS, and Windows, and drops cleanly into containers and every major serverless platform.

// server.js — minimal HTTP server
import { createServer } from 'node:http';

const server = createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({ message: 'Hello from Node.js', path: req.url }));
});

server.listen(3000, () => console.log('Listening on http://localhost:3000'));
V8
JIT-compiled JavaScript engine
libuv
Cross-platform async I/O layer
ESM
Native modules, top-level await
Workers
True parallelism for CPU work

Where it fits

In production

Nginx front door

Nginx terminates TLS, serves static assets and compresses responses, then forwards dynamic requests to Node on a local port with proxy_pass.

Reverse proxy

One public entry point hides the app topology, adds request/response headers, rate limiting, gzip, and edge caching, and lets you deploy new versions behind a stable address.

Load balancer

Node is single-threaded, so run one process per core (cluster, PM2, or containers) and spread traffic across them with an upstream block using least_conn and passive health checks.

# /etc/nginx/conf.d/app.conf — reverse proxy + load balancing
upstream node_app {
    least_conn;
    server 127.0.0.1:3000 max_fails=3 fail_timeout=15s;
    server 127.0.0.1:3001 max_fails=3 fail_timeout=15s;
    server 127.0.0.1:3002 backup;
    keepalive 32;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    location /assets/ { root /var/www/app/public; expires 30d; }

    location / {
        proxy_pass         http://node_app;
        proxy_http_version 1.1;
        proxy_set_header   Host              $host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_set_header   Upgrade           $http_upgrade;
        proxy_set_header   Connection        "upgrade";
        proxy_next_upstream error timeout http_502 http_503;
    }
}