Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

Node.js — Administrator & Developer Guide

Generated May 2026 from nodejs/node at 978a8c4

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

An exhaustive reference for engineers, SREs, distribution maintainers, and platform architects who build, deploy, operate, harden, and extend Node.js — the open-source, cross-platform JavaScript runtime built on the V8 engine and libuv asynchronous I/O library. This guide covers everything beneath the application layer: compilation, configuration, security hardening, performance tuning, diagnostics, and deep internals.

For everyday usage — running scripts, installing packages, using the REPL, HTTP servers, and the built-in test runner — see the User Guide.


1. Architecture Overview

1.1 What Node.js Is

Node.js is a single-binary, event-driven JavaScript runtime that executes JavaScript outside the browser. It embeds Google's V8 JavaScript engine for JIT compilation of JavaScript and WebAssembly, couples it with libuv for cross-platform asynchronous I/O, and wraps both in a C++ binding layer that exposes operating system primitives — file systems, networking, cryptography, process management, and more — to JavaScript applications through a standard library of built-in modules.

The runtime follows a single-threaded event loop model for JavaScript execution, delegating blocking operations (file I/O, DNS resolution, compression) to a thread pool managed by libuv. This architecture delivers high concurrency for I/O-bound workloads without the complexity of shared-memory threading. For CPU-bound work, the worker_threads module provides true parallelism with message-passing between isolates.

Node.js ships as a single statically-linked executable (node or node.exe) that bundles 20+ C/C++ dependencies, a JavaScript standard library of 55+ modules, and tooling including a CLI debugger, a built-in test runner, an HTTP/2 server, experimental QUIC support, the Chrome DevTools inspector protocol, and npm (installed alongside). The codebase spans 12,024 files at commit 978a8c40.

Note

Node.js is not a web framework. It is a runtime — the layer that frameworks like Express, Fastify, Koa, and Nest.js run on top of. This guide covers the runtime itself.

1.2 Architecture Diagram

┌─────────────────────────────────────────────────────────────────────┐
│                     JavaScript Application                          │
├─────────────────────────────────────────────────────────────────────┤
│              Node.js Standard Library (lib/)                        │
│  fs, http, https, net, crypto, stream, child_process, worker_threads│
│  path, url, os, util, events, buffer, dns, tls, zlib, vm, assert   │
│  test, readline, cluster, dgram, http2, perf_hooks, diagnostics_ch │
├──────────────┬──────────────────────────────────────────────────────┤
│  Internal    │          Internal Modules (lib/internal/)             │
│  Bindings    │  abort_controller, blob, buffer, child_process,      │
│  (C++ ↔ JS)  │  crypto, encoding, errors, event_target, fs, http,   │
│              │  modules/{cjs,esm}, process, streams, test_runner,   │
│              │  timers, tls, url, util, v8, vm, watch_mode, worker  │
├──────────────┴──────────────────────────────────────────────────────┤
│                   C++ Binding Layer (src/ — 151 files)               │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌─────────┐ │
│  │  crypto/  │ │  quic/   │ │inspector/│ │permission/ │ │tracing/ │ │
│  │ 31 files  │ │ 18 files │ │ 20 files │ │ 10 files   │ │ 6 files │ │
│  │  138K ch  │ │  159K ch │ │  39K ch  │ │  19K ch    │ │ 115K ch │ │
│  └──────────┘ └──────────┘ └──────────┘ └───────────┘ └─────────┘ │
├─────────────────────────────────────────────────────────────────────┤
│                       Dependencies (deps/)                          │
│  ┌────┐ ┌─────┐ ┌───────┐ ┌──────┐ ┌─────┐ ┌────┐ ┌───────────┐ │
│  │ V8 │ │libuv│ │OpenSSL│ │llhttp│ │c-ares│ │zlib│ │  nghttp2  │ │
│  └────┘ └─────┘ └───────┘ └──────┘ └─────┘ └────┘ └───────────┘ │
│  ┌────────┐ ┌───────┐ ┌─────────┐ ┌───┐ ┌──────┐ ┌────────────┐ │
│  │simdutf │ │simdjson│ │ brotli  │ │ada│ │sqlite│ │ngtcp2/ngh3 │ │
│  └────────┘ └───────┘ └─────────┘ └───┘ └──────┘ └────────────┘ │
├─────────────────────────────────────────────────────────────────────┤
│                    Operating System (via libuv)                      │
│           epoll / kqueue / IOCP / event ports / poll                 │
└─────────────────────────────────────────────────────────────────────┘

1.3 Component Inventory

Component Path Role
V8 deps/v8/ JavaScript/WebAssembly JIT compiler and garbage collector
libuv deps/uv/ Cross-platform async I/O, event loop, thread pool, timers
llhttp deps/llhttp/ HTTP/1.1 request/response parser (replaces http-parser)
OpenSSL deps/openssl/ TLS/SSL, cryptographic primitives, FIPS support
c-ares deps/cares/ Asynchronous DNS resolver
ICU deps/icu-small/ Unicode and internationalization (Intl, RegExp Unicode)
zlib deps/zlib/ Compression (gzip, deflate, brotli via separate dep)
nghttp2 deps/nghttp2/ HTTP/2 protocol implementation
brotli deps/brotli/ Brotli compression algorithm
simdutf deps/simdutf/ SIMD-accelerated UTF-8/UTF-16 validation and transcoding
simdjson deps/simdjson/ SIMD-accelerated JSON parsing
ada deps/ada/ WHATWG URL parser (fast, spec-compliant)
sqlite deps/sqlite/ Embedded SQL database engine (node:sqlite)
ngtcp2 deps/ngtcp2/ QUIC protocol implementation
nghttp3 deps/nghttp3/ HTTP/3 protocol over QUIC
LIEF Single Executable Application resource injection
libffi src/ (2 files) Foreign Function Interface (experimental)
undici deps/undici/ HTTP client (backing fetch() implementation)
cjs-module-lexer deps/cjs-module-lexer/ Fast CommonJS named-export detection
acorn deps/acorn/ JavaScript parser used by internal tooling
googletest deps/googletest/ C++ unit testing framework for native tests

1.4 Technology Stack

Layer Technology
Language (runtime core) C++17
Language (standard library) JavaScript (ES2024+)
Build system GYP (Generate Your Projects) via configure.py + node_gyp
Build backends make, ninja
JavaScript engine V8 (current V8 version bundled with release)
Event loop libuv
HTTP parsing llhttp
TLS OpenSSL (3.x)
Package manager npm (bundled)
Test framework Built-in node:test + custom harness in test/common/
Documentation Markdown in doc/api/, processed by tools/doc/
CI GitHub Actions, Jenkins

1.5 Data Flow

Event Loop Cycle

   ┌───────────────────────────┐
   │      timers (setTimeout,  │
   │      setInterval)         │
   └───────────┬───────────────┘
               │
   ┌───────────▼───────────────┐
   │   pending callbacks       │
   │   (deferred I/O callbacks)│
   └───────────┬───────────────┘
               │
   ┌───────────▼───────────────┐
   │   idle, prepare           │
   │   (internal use)          │
   └───────────┬───────────────┘
               │
   ┌───────────▼───────────────┐
   │   poll                    │  ← epoll/kqueue/IOCP waits here
   │   (I/O callbacks)         │    for new I/O events
   └───────────┬───────────────┘
               │
   ┌───────────▼───────────────┐
   │   check (setImmediate)    │
   └───────────┬───────────────┘
               │
   ┌───────────▼───────────────┐
   │   close callbacks         │
   │   (socket.on('close'))    │
   └───────────┘
               │
   process.nextTick() and      ← runs between EVERY phase
   microtask queue (Promises)

Module Resolution Flow

  1. require('module') or import 'module' invoked
  2. If node: prefix, load built-in module directly from lib/
  3. Check node_modules/ hierarchy (CJS) or resolve via package.json exports map (ESM)
  4. CJS: lib/internal/modules/cjs/loader.js — synchronous Module._resolveFilename() → Module._load() → compile → cache
  5. ESM: lib/internal/modules/esm/ — async resolve() → load() → translate() → instantiate() through loader chain
  6. Native addons (.node files): process.dlopen() → dynamic library load → napi_register_module_v1 init

HTTP Request Lifecycle

  1. TCP connection arrives → libuv accepts → net.Socket created
  2. Data arrives → libuv callback → llhttp parses HTTP headers/body
  3. http.IncomingMessage + http.ServerResponse objects created
  4. User handler invoked (request event)
  5. Response written → buffered by streams → flushed to socket
  6. Socket drained → keep-alive or close

2. System Requirements

2.1 Supported Platforms

Platform Architectures Tier
Linux (glibc ≥ 2.28) x64, arm64, armv7, ppc64le, s390x, riscv64, loong64 Tier 1 (x64, arm64), Tier 2 (others)
macOS (≥ 11.0) x64, arm64 (Apple Silicon) Tier 1
Windows (≥ 10 / Server 2016) x64, arm64 Tier 1 (x64), Tier 2 (arm64)
FreeBSD (≥ 13) x64 Tier 2
SmartOS (illumos) x64 Tier 2
IBM i (PASE) ppc64 Tier 2
z/OS s390x Tier 2
Android arm64 Experimental
MIPS-based Linux mips64el Experimental

2.2 Architecture Support Matrix

Architecture Linux macOS Windows
x64 (amd64) Full Full Full
arm64 (aarch64) Full Full (M1/M2/M3+) Supported
armv7 (32-bit ARM) Supported N/A N/A
ppc64le Supported N/A N/A
s390x Supported N/A N/A
riscv64 Experimental N/A N/A
loong64 Experimental N/A N/A

2.3 Build Prerequisites

Prerequisite Version Notes
Python 3.8+ Required for configure.py and GYP build generation
C++ compiler GCC 10.1+ / Clang 8+ / MSVC 2022+ Must support C++17
make GNU Make 3.81+ Or ninja as alternative
ninja 1.7+ Optional, faster builds (--ninja)
Git 2.x For cloning and development
nasm 2.13+ Required for OpenSSL asm on x86/x64
pkg-config Any For detecting shared libraries
ccache Any Optional, speeds up rebuilds

Linux (Debian/Ubuntu):

sudo apt-get install -y python3 g++ make git nasm pkg-config

Linux (RHEL/Fedora):

sudo dnf install -y python3 gcc-c++ make git nasm pkg-config

macOS:

xcode-select --install  # Installs clang, make, git
brew install python nasm

Windows:

Install Visual Studio 2022 with "Desktop development with C++" workload. Python 3 must be on PATH. The build uses vcbuild.bat instead of configure.py/make.

2.4 Build Configuration — configure.py Reference

The configure.py script accepts 190+ flags via argparse, generating GYP build files. Flags are grouped by category below.

General Build Options

Flag Default Description
--prefix /usr/local Installation prefix directory
--dest-cpu auto-detect Target CPU: x64, arm, arm64, ia32, mips64el, ppc64, riscv64, s390x, loong64
--dest-os auto-detect Target OS: linux, mac, win, freebsd, android, aix
--ninja off Generate ninja build files instead of Makefiles
--verbose off Verbose build output
--tag (none) Custom build tag
--release-urlbase (none) Base URL for release downloads
--enable-d8 off Build V8's d8 shell
--gdb off Add GDB support
--no-ifaddrs off Disable getifaddrs() usage
--fully-static off Generate fully static binary
--partly-static off Static libgcc/libstdc++, shared libc
--write-snapshot off Write a startup snapshot blob
--without-npm off Do not install npm
--without-corepack off Do not install corepack
--with-snapshot on Build with V8 snapshot for faster startup
--without-snapshot off Build without V8 snapshot
--node-snapshot-main (none) Main script for custom startup snapshot
--coverage off Build with code coverage instrumentation
--error-on-warn off Treat compiler warnings as errors

Debug Options

Flag Default Description
--debug off Build with debug symbols (-g), no optimization
--debug-node off Debug Node.js C++ only (not V8 or deps)
--debug-lib off No-op; debug JS with --inspect at runtime
--enable-asan off Build with AddressSanitizer
--enable-msan off Build with MemorySanitizer
--enable-tsan off Build with ThreadSanitizer
--enable-ubsan off Build with UndefinedBehaviorSanitizer
--enable-lsan off Build with LeakSanitizer
--enable-static-analysis off Enable Clang static analysis
--v8-lite-mode off V8 lite mode (reduced memory, no JIT)
--v8-enable-disassembler off Enable V8 disassembler
--v8-enable-object-print off Enable V8 object printing
--v8-enable-hugepage off V8 hugepage support (Linux)
--v8-enable-short-builtin-calls off Short builtin calls (perf optimization)
--v8-enable-31bit-smis-on-64bit-arch off 31-bit SMIs on 64-bit
--v8-enable-pointer-compression varies V8 pointer compression
--v8-enable-shared-ro-heap off Shared read-only heap across isolates
--v8-enable-i18n-support on V8 internationalization support
--v8-enable-inspector on V8 inspector protocol support

Shared Library Options

Flag Default Description
--shared off Build libnode as a shared library
--shared-http-parser off Link against system llhttp (not bundled)
--shared-libuv off Link against system libuv
--shared-nghttp2 off Link against system nghttp2
--shared-openssl off Link against system OpenSSL
--shared-zlib off Link against system zlib
--shared-brotli off Link against system brotli
--shared-cares off Link against system c-ares
--shared-ngtcp2 off Link against system ngtcp2
--shared-nghttp3 off Link against system nghttp3
--shared-simdjson off Link against system simdjson
--shared-simdutf off Link against system simdutf
--shared-sqlite off Link against system sqlite
--shared-ada off Link against system ada URL parser
--shared-uvwasi off Link against system uvwasi
--with-ltcg off Link-Time Code Generation (MSVC only)
--without-bundled-v8 off Use system V8 (advanced, rarely used)

For each --shared-* flag, corresponding --shared-*-includes and --shared-*-libpath flags specify custom include and library paths.

Crypto / SSL Options

Flag Default Description
--openssl-conf-name nodejs_conf OpenSSL configuration section name
--openssl-default-cipher-list (OpenSSL default) Override default TLS cipher list
--openssl-no-asm off Disable OpenSSL assembly optimizations
--openssl-fips off Build OpenSSL with FIPS module
--openssl-is-fips off Report crypto.getFips() as enabled
--openssl-use-def-ca-store off Use OpenSSL's default CA store
--openssl-system-ca-path (none) Path to system CA certificates
--without-ssl off Build without TLS/crypto support entirely
--without-node-options off Disallow NODE_OPTIONS env var

Important

Building with --without-ssl disables the crypto, tls, https, and http2 modules entirely. Most production applications require TLS. Only use this for deeply embedded or constrained environments.

ICU / Internationalization Options

Flag Default Description
--with-intl full-icu ICU mode: full-icu (all locales), small-icu (English only), system-icu, none
--with-icu-source (bundled) Path to custom ICU source tarball or directory
--with-icu-default-data-dir (none) Default ICU data directory at runtime
--without-intl off Alias for --with-intl=none
--download none Download missing ICU data during configure

Platform-Specific Options

Flag Platform Description
--enable-pgo-generate Linux/macOS Emit profile data for PGO builds (step 1)
--enable-pgo-use Linux/macOS Use PGO profile data for optimized build (step 2)
--cross-compiling Any Force cross-compilation mode
--link-module Any Additional JS module to link into the binary
--node-builtin-modules-path Any Override path for built-in JS modules (development)
--enable-vtune-profiling Linux/Windows Enable Intel VTune Profiler integration
--enable-etw Windows Enable Event Tracing for Windows
--with-ossfuzz Linux Build for OSS-Fuzz fuzzing
--with-arm-float-abi ARM Float ABI: hard, soft, softfp
--with-arm-fpu ARM ARM FPU: vfp, vfpv3, vfpv3-d16, neon
--with-mips-arch-variant MIPS MIPS variant: r1, r2, r6
--with-mips-fpu-mode MIPS MIPS FPU: fp32, fp64, fpxx

Experimental Options

Flag Default Description
--experimental-http-parser off Use experimental HTTP parser
--node-use-node-snapshot on Use Node.js startup snapshot
--without-node-snapshot off Disable Node.js snapshot
--without-node-code-cache off Disable Node.js code cache
--disable-single-executable-application off Disable SEA support

2.5 Building from Source

Standard build:

git clone https://github.com/nodejs/node.git
cd node
./configure
make -j$(nproc)
# Binary at ./out/Release/node

Ninja build (faster):

./configure --ninja
ninja -C out/Release

Debug build:

./configure --debug
make -j$(nproc)
# Binary at ./out/Debug/node

Installation:

sudo make install
# Installs to /usr/local by default
# Change with: ./configure --prefix=/opt/node

Windows build:

vcbuild.bat release x64
:: Binary at Release\node.exe

Profile-Guided Optimization (PGO):

# Step 1: Build instrumented binary
./configure --enable-pgo-generate
make -j$(nproc)
# Step 2: Run workload to generate profile data
./out/Release/node your-benchmark.js
# Step 3: Build optimized binary using profile
./configure --enable-pgo-use
make -j$(nproc)

3. Configuration Reference

3.1 Runtime Environment Variables

Variable Default Description
NODE_ENV (unset) Application environment. production disables some dev features. Not read by Node.js core, but widely used by frameworks.
NODE_OPTIONS (unset) Space-separated list of CLI flags applied before command-line flags. Security-sensitive: can inject --require. Disable with --without-node-options at build time.
NODE_PATH (unset) Colon-separated (; on Windows) list of directories prepended to module search path. Legacy; prefer node_modules hierarchy.
NODE_DEBUG (unset) Comma-separated list of core modules to emit debug output: fs, http, net, tls, module, timer, stream, child_process, cluster.
NODE_DEBUG_NATIVE (unset) Enable debug output for C++ internals.
NODE_TLS_REJECT_UNAUTHORIZED 1 Set to 0 to disable TLS certificate validation. Never use in production.
NODE_EXTRA_CA_CERTS (unset) Path to PEM file with extra CA certificates appended to the default trust store.
NODE_ICU_DATA (unset) Path to ICU data file for small-icu builds that need full locale data at runtime.
NODE_NO_WARNINGS (unset) Set to 1 to suppress all process warnings.
NODE_PENDING_DEPRECATION (unset) Set to 1 to emit pending deprecation warnings.
NODE_PENDING_PIPE_INSTANCES 4 Number of pending pipe instances for IPC on Windows.
NODE_REDIRECT_WARNINGS (unset) Path to file for writing warnings instead of stderr.
NODE_REPL_HISTORY ~/.node_repl_history Path to REPL history file. Set to empty string to disable.
NODE_REPL_EXTERNAL_MODULE (unset) Path to alternative REPL module.
NODE_DISABLE_COLORS (unset) Set to 1 to disable ANSI colors in REPL and util output.
NODE_V8_COVERAGE (unset) Directory to write V8 code coverage data (JSON).
NODE_COMPILE_CACHE (unset) Directory for module compile cache. Speeds up repeated startup.
NODE_CHANNEL_FD (unset) File descriptor for parent/child IPC channel (internal).
NODE_CLUSTER_SCHED_POLICY rr Cluster scheduling: rr (round-robin) or none (OS-decided).
NODE_UNIQUE_ID (unset) Cluster worker ID (set automatically by cluster master).
NODE_TEST_CONTEXT (unset) Internal test runner context variable.
UV_THREADPOOL_SIZE 4 libuv thread pool size (1–1024). Affects fs, dns.lookup(), crypto, zlib.
UV_USE_IO_URING 0 Set to 1 to enable io_uring on Linux (experimental in libuv).
OPENSSL_CONF (system) Path to OpenSSL configuration file.
SSL_CERT_DIR (system) Directory containing CA certificates in PEM format.
SSL_CERT_FILE (system) Path to CA certificate bundle file.
TZ (system) Timezone for Date objects. Uses ICU/system timezone database.
FORCE_COLOR (unset) Force color output (0=none, 1=16 colors, 2=256, 3=16M).
NO_COLOR (unset) Disable all color output (any value).
NODE_MACOSX_PERF (unset) Enable macOS performance tools integration.

Important

NODE_OPTIONS is a powerful injection point. In multi-tenant or shared hosting environments, restrict it by building Node.js with --without-node-options or by clearing it in process startup scripts.

3.2 package.json Configuration

Field Type Description
"type" "module" or "commonjs" Module system for .js files. "module" = ESM, "commonjs" = CJS (default).
"main" string CJS entry point (used when package is require()d).
"exports" object/string Conditional exports map. Controls what consumers can import/require.
"imports" object Subpath imports — private package-internal import mappings (e.g., #utils).
"engines" object Engine version constraints: { "node": ">=18.0.0" }. Advisory only unless enforced by package manager.
"scripts" object Lifecycle scripts: start, test, preinstall, postinstall, etc.
"bin" string/object CLI executable mappings.
"files" array Allowlist of files to include when publishing.
"dependencies" object Production dependencies.
"devDependencies" object Development-only dependencies.
"peerDependencies" object Peer dependency declarations.
"optionalDependencies" object Optional dependencies (install failures non-fatal).
"overrides" object Dependency version overrides (npm) / "resolutions" (yarn).

3.3 OpenSSL Configuration

Node.js loads OpenSSL configuration from the section specified by --openssl-conf-name (default: nodejs_conf) in the OpenSSL config file. Override the config file path with the OPENSSL_CONF environment variable.

# /etc/ssl/openssl.cnf (excerpt)
[nodejs_conf]
ssl_conf = ssl_sect

[ssl_sect]
system_default = system_default_sect

[system_default_sect]
MinProtocol = TLSv1.2
CipherString = DEFAULT:@SECLEVEL=2

3.4 V8 Flags Passthrough

V8 accepts hundreds of tuning flags passed through --v8-options or via NODE_OPTIONS:

# List all V8 flags
node --v8-options

# Pass specific V8 flags
node --max-old-space-size=8192 --max-semi-space-size=64 app.js

# Experimental V8 features
node --harmony-temporal app.js

Key V8 flags for production tuning are covered in Section 6 (Performance).


4. Deployment & Scaling

4.1 Production Deployment Patterns

Process Manager Deployment (PM2)

# Install PM2
npm install -g pm2

# Start application with clustering
pm2 start app.js -i max --name my-app

# Save process list for system restart
pm2 save
pm2 startup systemd

systemd Service

# /etc/systemd/system/node-app.service
[Unit]
Description=Node.js Application
After=network.target

[Service]
Type=simple
User=nodeapp
WorkingDirectory=/opt/app
ExecStart=/usr/local/bin/node --max-old-space-size=4096 app.js
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=/opt/app/data
PrivateTmp=true

[Install]
WantedBy=multi-user.target
sudo systemctl enable node-app
sudo systemctl start node-app

4.2 Docker Deployment

# Multi-stage build
FROM node:22-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .

FROM node:22-slim
WORKDIR /app
COPY --from=build /app .
USER node
EXPOSE 3000
ENV NODE_ENV=production
CMD ["node", "app.js"]

Tip

Use node:22-slim (Debian slim) or node:22-alpine for smaller images. The slim variant is ~200MB vs ~1GB for the full image. Alpine uses musl libc, which can cause subtle compatibility issues with native addons.

Docker health check:

HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
  CMD node -e "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"

4.3 Cluster Module (Multi-Process)

The cluster module forks the Node.js process to utilize multiple CPU cores:

import cluster from 'node:cluster';
import http from 'node:http';
import os from 'node:os';

if (cluster.isPrimary) {
  const cpuCount = os.cpus().length;
  for (let i = 0; i < cpuCount; i++) {
    cluster.fork();
  }
  cluster.on('exit', (worker, code, signal) => {
    console.error(`Worker ${worker.process.pid} died (${signal || code}). Restarting...`);
    cluster.fork();
  });
} else {
  http.createServer((req, res) => {
    res.writeHead(200);
    res.end('OK');
  }).listen(3000);
}

Scheduling policy is controlled by NODE_CLUSTER_SCHED_POLICY:

  • rr (default on all platforms except Windows): Round-robin distribution by the primary process.
  • none: OS decides which worker gets the connection (can lead to uneven distribution).

4.4 Worker Threads (Multi-Threaded)

Worker threads share the same process and can share memory via SharedArrayBuffer:

import { Worker, isMainThread, parentPort, workerData } from 'node:worker_threads';

if (isMainThread) {
  const worker = new Worker(new URL(import.meta.url), {
    workerData: { input: [1, 2, 3, 4, 5] }
  });
  worker.on('message', (result) => console.log('Result:', result));
} else {
  const sum = workerData.input.reduce((a, b) => a + b, 0);
  parentPort.postMessage(sum);
}

Worker threads are best for CPU-intensive operations (image processing, compression, ML inference). For I/O-bound work, the event loop with async I/O is more efficient.

4.5 Single Executable Applications (SEA)

Build a standalone binary that bundles the application into the Node.js executable:

// sea-config.json
{
  "main": "app.js",
  "output": "sea-prep.blob",
  "disableExperimentalSEAWarning": true,
  "useSnapshot": false,
  "useCodeCache": true,
  "assets": {
    "icon.png": "assets/icon.png"
  }
}
# 1. Generate the SEA preparation blob
node --experimental-sea-config sea-config.json

# 2. Copy the Node.js binary
cp $(which node) my-app

# 3. Inject the blob into the binary
# Linux:
npx postject my-app NODE_SEA_BLOB sea-prep.blob \
  --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2

# macOS: add --macho-segment-name NODE_SEA
# Windows: use signtool for code signing after injection

4.6 Startup Snapshots

Build a snapshot of application startup state into the binary for near-instant cold starts:

# Build Node.js with custom snapshot
./configure --node-snapshot-main=app.js
make -j$(nproc)
# The resulting binary starts with app.js already initialized

Runtime snapshot building:

node --build-snapshot --snapshot-blob snapshot.blob app.js
node --snapshot-blob snapshot.blob

Note

Snapshots capture the V8 heap state at snapshot time. Not all objects serialize correctly — avoid capturing open file descriptors, network sockets, or native addon state in the snapshot.


5. Operations

5.1 Health Monitoring

// health.js — production health check endpoint
import http from 'node:http';
import v8 from 'node:v8';
import os from 'node:os';

http.createServer((req, res) => {
  if (req.url === '/health') {
    const heap = v8.getHeapStatistics();
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({
      status: 'ok',
      uptime: process.uptime(),
      memory: {
        rss: process.memoryUsage.rss(),
        heapUsed: heap.used_heap_size,
        heapTotal: heap.total_heap_size,
        heapLimit: heap.heap_size_limit,
        external: process.memoryUsage().external
      },
      cpu: process.cpuUsage(),
      eventLoopLag: performance.now(), // measure with perf_hooks for real lag
      pid: process.pid,
      loadAvg: os.loadavg()
    }));
  }
}).listen(9090);

Tip

Use perf_hooks.monitorEventLoopDelay() for production-grade event loop monitoring. A histogram-based approach is more accurate than sampling:

import { monitorEventLoopDelay } from 'node:perf_hooks';
const h = monitorEventLoopDelay({ resolution: 20 });
h.enable();
// h.percentile(99) gives p99 event loop delay in nanoseconds

5.2 Diagnostic Reports

Diagnostic reports produce a JSON summary of process state (stack traces, heap stats, libuv handles, environment, loaded modules) for post-mortem debugging:

# Generate on signal
node --report-on-signal app.js
kill -USR2 <pid>

# Generate on fatal error (uncaught exception, OOM)
node --report-on-fatalerror app.js

# Generate on uncaught exception
node --report-uncaught-exception app.js

# Generate programmatically
node -e "process.report.writeReport('report.json')"

# Configure report directory and filename
node --report-directory=/var/log/node-reports --report-filename=diag-{pid}-{datetime}.json app.js

# Compact report format
node --report-compact app.js

Report output includes:

  • Header (event, date, PID, Node.js/V8/libuv versions)
  • JavaScript stack trace
  • Native stack trace
  • Heap statistics
  • Resource usage (user CPU, system CPU, max RSS)
  • libuv handle summary (active handles/requests)
  • Environment variables
  • Loaded shared libraries
  • Workers (if any)

5.3 CPU Profiling

# V8 CPU profiler (outputs .cpuprofile for Chrome DevTools)
node --cpu-prof --cpu-prof-dir=./profiles --cpu-prof-interval=100 app.js

# V8 tick processor profiling (lower level)
node --prof app.js
node --prof-process isolate-0x*.log > profile.txt

# Linux perf integration
perf record -g node --perf-basic-prof app.js
perf report

5.4 Heap Analysis

# Heap snapshot on signal
node --heapsnapshot-signal=SIGUSR2 app.js
kill -USR2 <pid>
# Produces Heap.*.heapsnapshot — load in Chrome DevTools

# Programmatic heap snapshot
node -e "
const v8 = require('v8');
const fs = require('fs');
const snapshotStream = v8.writeHeapSnapshot();
console.log('Heap snapshot written to:', snapshotStream);
"

# Heap profiling (allocation tracking)
node --heap-prof --heap-prof-dir=./profiles app.js

Tip

For memory leak detection in production, use --heapsnapshot-signal to take snapshots on demand without restarting. Compare snapshots in Chrome DevTools to identify retained objects.

5.5 Tracing

Node.js includes a built-in tracing system compatible with Chrome's chrome://tracing:

# Enable trace events
node --trace-events-enabled --trace-event-categories=v8,node,node.async_hooks app.js

# Available trace categories:
# v8                    - V8 engine events (GC, compilation)
# node                  - Node.js core events
# node.async_hooks      - Async hooks trace events
# node.bootstrap        - Bootstrap/startup events
# node.environment      - Environment lifecycle
# node.fs.sync          - Synchronous fs operations
# node.fs.async         - Asynchronous fs operations
# node.net.native       - Network events (TCP, DNS)
# node.dns.native       - DNS resolution events
# node.perf             - Performance events
# node.perf.usertiming  - User timing marks/measures
# node.perf.timerify    - Timerified function traces

# Output is written to node_trace.*.log in the current directory

The tracing subsystem is implemented in src/tracing/ (6 files, 115K chars) and integrates with V8's trace event infrastructure.

5.6 Inspector Protocol

Node.js implements the Chrome DevTools Protocol (CDP) for debugging, profiling, and automation:

# Start with inspector (accepts connections on 127.0.0.1:9229)
node --inspect app.js

# Break on first line
node --inspect-brk app.js

# Listen on all interfaces (CAUTION: security risk)
node --inspect=0.0.0.0:9229 app.js

# Wait for debugger to attach before starting
node --inspect-wait app.js

# Inspect in a running process
kill -SIGUSR1 <pid>  # Opens inspector on default port

Warning

Never expose the inspector port to untrusted networks. The inspector protocol allows arbitrary code execution. Use SSH tunneling or a reverse proxy with authentication for remote debugging:

ssh -L 9229:localhost:9229 user@remote-host

The inspector implementation lives in src/inspector/ (20 files, 39K chars) and includes WebSocket transport, V8 inspector client bindings, and the inspector module API.

5.7 Watch Mode

# Restart on file changes (built-in, no external tools needed)
node --watch app.js

# Watch mode with path filtering
node --watch-path=./src --watch-path=./config app.js

# Watch mode preserves the process state (experimental)
node --watch-preserve-output app.js

Watch mode is implemented in lib/internal/watch_mode/ and uses fs.watch() (backed by inotify/FSEvents/ReadDirectoryChangesW) for efficient file system monitoring.

5.8 Graceful Shutdown

// Graceful shutdown pattern
const server = http.createServer(handler);
server.listen(3000);

const connections = new Set();
server.on('connection', (conn) => {
  connections.add(conn);
  conn.on('close', () => connections.delete(conn));
});

function shutdown(signal) {
  console.log(`Received ${signal}. Graceful shutdown...`);

  // Stop accepting new connections
  server.close(() => {
    console.log('Server closed. Exiting.');
    process.exit(0);
  });

  // Set a hard timeout
  setTimeout(() => {
    console.error('Forced shutdown after timeout');
    process.exit(1);
  }, 30000).unref();

  // Destroy idle connections
  for (const conn of connections) {
    conn.end();
  }
}

process.on('SIGTERM', () => shutdown('SIGTERM'));
process.on('SIGINT', () => shutdown('SIGINT'));

Note

.unref() on the timeout timer prevents it from keeping the event loop alive. Without it, the process would wait the full 30 seconds even if all connections close immediately.


6. Performance

6.1 Event Loop Optimization

The event loop is the heart of Node.js performance. Key principles:

  1. Never block the event loop — long synchronous operations (JSON.parse on large payloads, RegExp backtracking, synchronous crypto) stall all concurrent connections.
  2. Partition CPU work — use setImmediate() to break large synchronous tasks across event loop ticks.
  3. Offload to worker threads — CPU-intensive operations (image encoding, hashing large files) should use worker_threads.
  4. Monitor event loop delay — p99 > 100ms indicates problems.
// Partition a large array operation
function processChunk(items, index, chunkSize, callback) {
  const end = Math.min(index + chunkSize, items.length);
  for (let i = index; i < end; i++) {
    // process items[i]
  }
  if (end < items.length) {
    setImmediate(() => processChunk(items, end, chunkSize, callback));
  } else {
    callback();
  }
}

6.2 Large Pages

Large pages (huge pages) reduce TLB misses for the V8 code region, improving performance by 5-10% for some workloads:

# Linux: configure huge pages
sudo sysctl -w vm.nr_hugepages=100
echo 'vm.nr_hugepages=100' | sudo tee -a /etc/sysctl.conf

# Run Node.js with large pages
node --use-largepages=on app.js
# Options: on, silent (don't warn on failure), off

The large pages implementation lives in src/large_pages/ and maps the V8 code region to 2MB pages on Linux (or equivalent on other platforms).

6.3 V8 Tuning

Flag Default Description
--max-old-space-size ~1.7GB (64-bit) Maximum old generation heap size in MB. Increase for memory-intensive apps.
--max-semi-space-size 16MB Maximum semi-space (nursery) size in MB. Increase for high-allocation-rate apps.
--max-heap-size (calculated) Overall heap limit in MB.
--initial-old-space-size (calculated) Initial old generation size in MB.
--initial-heap-size (calculated) Initial heap size in MB. Pre-allocating reduces GC pauses during startup.
--optimize-for-size off Optimize V8 for memory usage over speed.
--always-compact off Force full GC compaction (slower but reduces fragmentation).
--expose-gc off Expose global.gc() for manual GC triggering.
--trace-gc off Log GC events to stderr.
--trace-gc-verbose off Verbose GC logging.
--gc-interval (auto) Force GC every N allocations (debugging only).
--noconcurrent-recompilation off Disable concurrent JIT compilation.
--predictable off Deterministic mode (disables concurrent GC/compilation). For testing.
# Production: 8GB heap, aggressive semi-space for high-throughput server
node --max-old-space-size=8192 --max-semi-space-size=64 app.js

# Memory-constrained environment (container with 512MB limit)
node --max-old-space-size=384 --optimize-for-size app.js

# Debug GC behavior
node --trace-gc --trace-gc-verbose app.js 2>gc.log

6.4 Startup Optimization

Technique Mechanism Speedup
Code cache V8 compiles and caches bytecode; subsequent loads skip parsing 10-30% startup
Startup snapshot Heap state serialized at build time; deserialized on start 40-70% startup
Compile cache NODE_COMPILE_CACHE dir caches compiled module bytecode across runs 10-30% startup
Lazy loading require() modules only when first used Proportional to unused modules
SEA with code cache "useCodeCache": true in SEA config Combined benefits
# Enable module compile cache
export NODE_COMPILE_CACHE=/tmp/node-compile-cache
node app.js  # First run: compiles and caches
node app.js  # Subsequent: loads from cache

6.5 Thread Pool Tuning

libuv's thread pool handles fs operations, dns.lookup(), and some crypto/zlib calls:

# Default: 4 threads. Max: 1024.
export UV_THREADPOOL_SIZE=16  # Must be set BEFORE process starts
node app.js

Guidelines:

  • Increase if fs or dns.lookup() latency is high under load
  • Don't over-provision — each thread consumes ~1MB stack. 64 threads = 64MB just for stacks
  • Use dns.resolve() (c-ares, async, not threadpool) instead of dns.lookup() (getaddrinfo, threadpool) for high-volume DNS

6.6 Benchmark Infrastructure

The benchmark/ directory contains a comprehensive benchmark suite:

# Run a specific benchmark
node benchmark/http/simple.js

# Run benchmark comparison between two Node.js builds
node benchmark/compare.js --old /path/to/old/node --new /path/to/new/node -- benchmark/http/

# Common benchmark categories:
# benchmark/http/       HTTP server throughput
# benchmark/fs/         File system operations
# benchmark/streams/    Stream throughput
# benchmark/buffers/    Buffer operations
# benchmark/url/        URL parsing
# benchmark/crypto/     Cryptographic operations
# benchmark/child_process/ Process spawning
# benchmark/events/     EventEmitter performance
# benchmark/net/        TCP networking
# benchmark/path/       Path operations
# benchmark/string_decoder/ String decoding
# benchmark/timers/     Timer performance

7. Security

7.1 Permission Model

Node.js implements an experimental permission model (since v20) that restricts what a Node.js process can do:

# Enable permission model (denies everything by default)
node --experimental-permission app.js

# Grant specific permissions
node --experimental-permission \
  --allow-fs-read=/app/data \
  --allow-fs-write=/app/output \
  app.js

# Allow child process spawning
node --experimental-permission \
  --allow-child-process \
  app.js

# Allow worker threads
node --experimental-permission \
  --allow-worker \
  app.js

# Allow native addons
node --experimental-permission \
  --allow-addons \
  app.js

# Wildcard patterns
node --experimental-permission \
  --allow-fs-read=/app/* \
  --allow-fs-write=/tmp/* \
  app.js

Warning

The permission model is experimental. It provides defense-in-depth but is not a security sandbox. Malicious native addons or V8 exploits can bypass it. Do not rely on it as the sole security boundary.

The permission system is implemented in src/permission/ (10 files, 19K chars):

Permission Class Scope
AddonPermission Loading native addon .node files
ChildProcessPermission Spawning child processes (child_process.spawn, exec, etc.)
FFIPermission Foreign Function Interface calls (experimental node:ffi)
FSPermission File system read/write access (path-based)
WorkerPermission Creating Worker threads

Check permissions programmatically:

if (process.permission.has('fs.read', '/etc/passwd')) {
  // Permission granted
}

7.2 TLS/SSL Configuration

import tls from 'node:tls';
import https from 'node:https';
import fs from 'node:fs';

const server = https.createServer({
  key: fs.readFileSync('private-key.pem'),
  cert: fs.readFileSync('certificate.pem'),
  ca: fs.readFileSync('ca-chain.pem'),

  // Minimum TLS version (default: TLSv1.2)
  minVersion: 'TLSv1.2',

  // Cipher suite configuration
  ciphers: [
    'TLS_AES_256_GCM_SHA384',
    'TLS_CHACHA20_POLY1305_SHA256',
    'TLS_AES_128_GCM_SHA256',
    'ECDHE-RSA-AES256-GCM-SHA384',
    'ECDHE-RSA-AES128-GCM-SHA256'
  ].join(':'),

  // ECDH curve
  ecdhCurve: 'auto',

  // Request client certificate
  requestCert: true,
  rejectUnauthorized: true,

  // Session resumption
  sessionTimeout: 300,

  // ALPN protocols
  ALPNProtocols: ['h2', 'http/1.1'],

  // Disable renegotiation (prevents DoS)
  // Node.js disables renegotiation by default since v16

  // OCSP stapling
  // Handled via 'OCSPRequest' event on tls.Server
}, handler);

Caution

Never set NODE_TLS_REJECT_UNAUTHORIZED=0 in production. It disables all certificate validation, making every TLS connection vulnerable to man-in-the-middle attacks. For self-signed certificates, use NODE_EXTRA_CA_CERTS or the ca option.

7.3 OpenSSL and FIPS Mode

Node.js links against OpenSSL 3.x for all cryptographic operations. FIPS 140-2/3 compliance requires:

# Build-time: configure with FIPS
./configure --openssl-fips

# Or: mark as FIPS-capable
./configure --openssl-is-fips

# Runtime: enable FIPS mode
node --enable-fips app.js

# Or force FIPS (error if cannot enable)
node --force-fips app.js
// Check FIPS status
import crypto from 'node:crypto';
console.log('FIPS enabled:', crypto.getFips());

// Enable FIPS programmatically
crypto.setFips(1);

7.4 Crypto Module Security

The src/crypto/ subsystem (31 files, 138K chars) wraps OpenSSL and exposes:

Area Considerations
Hashing Use sha256 or sha3-256 minimum. MD5 and SHA1 are broken for security purposes.
Symmetric encryption Use aes-256-gcm (authenticated) not aes-256-cbc (no integrity check).
Key derivation Use scrypt or argon2 (via native addon) for passwords. PBKDF2 with high iteration count as fallback.
Random bytes crypto.randomBytes() uses OpenSSL's CSPRNG. crypto.randomUUID() for UUIDs.
Timing attacks Use crypto.timingSafeEqual() for constant-time comparison.
Key management Use crypto.generateKeyPair() for RSA/EC keys. Minimum 2048-bit RSA, prefer Ed25519.

7.5 Supply Chain Security

# Audit dependencies for known vulnerabilities
npm audit

# Fix automatically where possible
npm audit fix

# Production install (no devDependencies, no scripts)
npm ci --only=production --ignore-scripts

# Lock file integrity
npm ci  # Always uses package-lock.json exactly

# Verify package signatures (npm v9+)
npm audit signatures
Issue Status Description
#62781 Open V8 SIGSEGV with pre-CVE code caches — loading code caches generated by older, vulnerable V8 versions can trigger a segmentation fault. Mitigation: regenerate code caches after Node.js upgrades.
#62774 Open Missing NULL checks in crypto/quic OpenSSL integration — potential crash on malformed QUIC packets. Affects experimental QUIC only.
#62326 Open dns.resolveSrv() returns ECONNREFUSED on Windows — DNS resolution issue specific to SRV records on Windows systems.

7.7 Security Best Practices

  1. Run as non-root — use a dedicated service account with minimal privileges
  2. Drop capabilities — on Linux, use setcap or systemd CapabilityBoundingSet
  3. Disable inspector in production — never expose --inspect ports
  4. Freeze prototypes — use --frozen-intrinsics (experimental) to prevent prototype pollution
  5. Policy-based module loading — use --experimental-policy with integrity checks
  6. Limit NODE_OPTIONS — build with --without-node-options or clear before launch
  7. HTTP header limits — --max-http-header-size (default 16KB) prevents header-based DoS
  8. Request timeout — set server.requestTimeout and server.headersTimeout

8. Developer Internals

8.1 Repository Structure

nodejs/node/
├── src/                    C++ binding layer (151 files, 1.3M chars)
│   ├── crypto/             OpenSSL wrappers (31 files, 138K)
│   ├── quic/               QUIC/HTTP3 protocol (18 files, 159K)
│   ├── inspector/          Chrome DevTools Protocol (20 files, 39K)
│   ├── permission/         Permission model (10 files, 19K)
│   ├── tracing/            Trace event infrastructure (6 files, 115K)
│   └── large_pages/        Huge page support
├── lib/                    JavaScript standard library
│   ├── *.js                55 top-level modules (898K chars)
│   └── internal/           52 internal modules (568K chars)
├── deps/                   Bundled C/C++ dependencies
│   ├── v8/                 V8 JavaScript engine
│   ├── uv/                 libuv async I/O
│   ├── openssl/            OpenSSL
│   ├── llhttp/             HTTP parser
│   ├── cares/              Async DNS
│   ├── icu-small/          ICU internationalization
│   ├── nghttp2/            HTTP/2
│   ├── ngtcp2/             QUIC
│   ├── nghttp3/            HTTP/3
│   ├── zlib/               Compression
│   ├── brotli/             Brotli compression
│   ├── simdutf/            SIMD UTF conversion
│   ├── simdjson/           SIMD JSON parsing
│   ├── ada/                URL parser
│   ├── sqlite/             SQLite
│   ├── undici/             HTTP client (fetch)
│   └── ...
├── test/                   Test suite (4,000+ files)
├── tools/                  Build and development tools
├── benchmark/              Performance benchmarks
├── doc/                    API documentation source
├── typings/                TypeScript type definitions for internal C++ bindings
└── configure.py            Build configuration script (190+ flags)

8.2 C++ Binding Layer (src/)

The C++ layer bridges V8 and the operating system. Key patterns:

Environment and Isolate

Every Node.js instance creates an Environment object (src/env.h, src/env.cc) that owns:

  • The V8 Isolate (single-threaded JS execution context)
  • The libuv event loop
  • All built-in module bindings
  • The async hooks state
  • The permission model
// Simplified binding registration pattern
void Initialize(Local<Object> target, Local<Value> unused,
                Local<Context> context, void* priv) {
  Environment* env = Environment::GetCurrent(context);
  // Register methods on target object
  SetMethod(context, target, "methodName", MethodCallback);
}
NODE_MODULE_CONTEXT_AWARE_INTERNAL(module_name, Initialize)

Key C++ Subsystems

Subsystem Files Size Purpose
src/crypto/ 31 138K Full OpenSSL integration: ciphers, hashes, keys, certificates, DH, ECDH, HKDF, PBKDF2, scrypt, sign/verify, X509
src/quic/ 18 159K QUIC transport protocol over UDP using ngtcp2/nghttp3. Experimental. Handles connection state, streams, congestion control, TLS 1.3 handshake
src/inspector/ 20 39K Chrome DevTools Protocol implementation: WebSocket transport, V8 inspector bindings, breakpoints, profiling, heap inspection
src/permission/ 10 19K Runtime permission checks: filesystem paths, child process, worker threads, native addons, FFI
src/tracing/ 6 115K Trace event recording compatible with Chrome tracing format. Categories for V8, Node core, async hooks
src/large_pages/ ~2 Small Memory mapping of V8 code region to huge pages (2MB) for TLB optimization
src/dataqueue.h/cc 2 — Internal data queue for blob/stream operations
FFI (src/) 2 2.6K Foreign Function Interface binding using libffi

8.3 JavaScript Standard Library (lib/)

55 top-level modules (898K chars total):

Module File Description
assert lib/assert.js Assertion testing
async_hooks lib/async_hooks.js Async resource lifecycle tracking
buffer lib/buffer.js Binary data handling (Buffer, Blob)
child_process lib/child_process.js Spawn/exec/fork child processes
cluster lib/cluster.js Multi-process server (primary/workers)
console lib/console.js Console output (log, warn, error, table)
crypto lib/crypto.js Cryptographic operations
dgram lib/dgram.js UDP datagram sockets
diagnostics_channel lib/diagnostics_channel.js Named publish/subscribe channels for diagnostics
dns lib/dns.js DNS resolution (lookup + resolve)
domain lib/domain.js Error handling domains (deprecated)
events lib/events.js EventEmitter class
fs lib/fs.js File system (sync, async, promises, watch)
http lib/http.js HTTP/1.1 client and server
http2 lib/http2.js HTTP/2 client and server
https lib/https.js HTTPS (HTTP over TLS)
inspector lib/inspector.js Inspector protocol bindings
module lib/module.js Module system access
net lib/net.js TCP/IPC networking
os lib/os.js Operating system info (cpus, memory, platform)
path lib/path.js File path manipulation (posix + win32)
perf_hooks lib/perf_hooks.js Performance measurement (marks, measures, observers)
process lib/process.js Process info and control
punycode lib/punycode.js Unicode/Punycode encoding (deprecated)
querystring lib/querystring.js URL query string parsing (legacy, prefer URLSearchParams)
readline lib/readline.js Line-by-line input reading
repl lib/repl.js Interactive Read-Eval-Print Loop
sqlite lib/sqlite.js SQLite database interface
stream lib/stream.js Stream base classes and utilities
string_decoder lib/string_decoder.js Buffer to string decoding
sys lib/sys.js Alias for util (deprecated)
test lib/test.js Built-in test runner
timers lib/timers.js setTimeout, setInterval, setImmediate
tls lib/tls.js TLS/SSL sockets
trace_events lib/trace_events.js Trace event management
tty lib/tty.js TTY stream handling
url lib/url.js URL parsing (WHATWG + legacy)
util lib/util.js Utilities (inspect, format, promisify, types)
v8 lib/v8.js V8 engine access (heap stats, serialization)
vm lib/vm.js Script execution in V8 contexts
wasi lib/wasi.js WebAssembly System Interface
worker_threads lib/worker_threads.js Multi-threaded JavaScript execution
zlib lib/zlib.js Compression (gzip, deflate, brotli)

8.4 Internal Modules (lib/internal/)

52 internal module directories/files (568K chars) — not accessible via require() from user code. Loaded via internalBinding() or internal require.

Internal Module Purpose
abort_controller AbortController/AbortSignal implementation (Web API)
blob Blob and File implementations (Web API)
buffer Buffer internals, FastBuffer (subclass of Uint8Array)
child_process Control class, spawn/exec internals, serialization
crypto Cipher, hash, key, certificate, DH, ECDH, random, scrypt implementations
encoding TextEncoder, TextDecoder (Web API)
errors Error class definitions, error code registry (907 error types)
event_target EventTarget, Event, NodeEventTarget (Web API compatibility)
file File class implementation
fixed_queue High-performance fixed-size circular queue
freelist Object pool pattern for reuse
fs File system internals (promises, streams, watchers, dir, cp, glob)
heap_utils HeapSnapshotStream, heap inspection utilities
histogram Histogram class for latency/performance tracking
http HTTP parser integration, header handling, date cache
js_stream_socket JavaScript-based stream socket implementation
locks Lock, LockManager (Web Locks API)
mime MIMEType, MIMEParams (MIME type parsing)
modules/cjs/ CommonJS loader (Module._resolveFilename, Module._load, Module.wrap)
modules/esm/ ESM loader chain (resolve, load, translate, hooks)
modules/helpers.js Shared module system utilities
navigator Navigator class (limited Web API compatibility)
process Process bootstrap, warning system, nextTick queue
readline Readline internals, completion, history
socket_list SocketAddress management for cluster IPC
socketaddress SocketAddress class
streams/ Stream implementation (readable, writable, duplex, transform, pipeline, compose)
test_runner/ Built-in test runner (test, describe, it, mock, coverage)
timers Timeout, Immediate classes, timer queue management
tls TLS context management, certificate chain handling
url WHATWG URL implementation (wraps ada parser)
util inspect, type checking, promisify, decorators
v8 V8 serialization, deserialization, heap statistics
vm Script, Module, SourceTextModule implementations
watch_mode File watcher for --watch mode
watchdog Execution timeout watchdog (for vm.runInNewContext timeouts)
webstreams Web Streams API (ReadableStream, WritableStream, TransformStream)
worker Worker thread bootstrap, messaging, BroadcastChannel

8.5 Error System

The error system (lib/internal/errors.js) defines 907 error types organized by category. Every Node.js error has a unique code (e.g., ERR_INVALID_ARG_TYPE) and a corresponding class.

Error Class Hierarchy

Error
├── NodeError (extends Error)
│   ├── ERR_INVALID_ARG_TYPE
│   ├── ERR_INVALID_ARG_VALUE
│   ├── ERR_MISSING_ARGS
│   ├── ERR_OUT_OF_RANGE
│   └── ... (hundreds more)
├── TypeError (NodeTypeError extends TypeError)
│   ├── ERR_INVALID_THIS
│   ├── ERR_INVALID_CALLBACK
│   └── ...
├── RangeError (NodeRangeError extends RangeError)
│   ├── ERR_BUFFER_OUT_OF_BOUNDS
│   ├── ERR_INDEX_OUT_OF_RANGE
│   └── ...
├── SystemError (extends NodeError)
│   ├── errno (libuv error code)
│   ├── syscall (system call name)
│   ├── path (file path, if applicable)
│   └── ... (wraps OS errors)
├── UVException (libuv errors)
│   ├── EACCES, ENOENT, EEXIST, EPERM, ...
│   └── ... (maps libuv errno → Node.js error)
└── AbortError (for AbortSignal cancellations)

Error Categories and Selected Codes

Argument Validation Errors:

Code Description
ERR_INVALID_ARG_TYPE Argument of wrong type (most common error)
ERR_INVALID_ARG_VALUE Argument value invalid/out-of-range
ERR_MISSING_ARGS Required argument(s) not provided
ERR_OUT_OF_RANGE Numeric argument outside acceptable range
ERR_INVALID_CALLBACK Callback argument is not a function
ERR_INVALID_THIS Method called with incorrect this context
ERR_FALSY_VALUE_REJECTION Promise rejected with falsy value

Module System Errors:

Code Description
ERR_MODULE_NOT_FOUND ES module not found
ERR_REQUIRE_ESM Attempted require() of ES module
ERR_REQUIRE_ASYNC_MODULE Attempted require() of async ES module
ERR_UNSUPPORTED_DIR_IMPORT Directory import not supported in ESM
ERR_PACKAGE_PATH_NOT_EXPORTED Package subpath not defined in exports
ERR_PACKAGE_IMPORT_NOT_DEFINED Package import not defined in imports map
ERR_UNKNOWN_FILE_EXTENSION Unknown file extension for module loading
ERR_INVALID_PACKAGE_CONFIG Invalid package.json configuration
ERR_INVALID_MODULE_SPECIFIER Invalid module specifier syntax

File System Errors:

Code Description
ERR_FS_FILE_TOO_LARGE File too large for operation
ERR_FS_INVALID_SYMLINK_TYPE Invalid symlink type
ERR_FS_CP_DIR_TO_NON_DIR Cannot copy directory to non-directory
ERR_FS_CP_EEXIST Target already exists (no overwrite)
ERR_FS_CP_EINVAL Invalid copy operation
ERR_FS_CP_FIFO_PIPE Cannot copy FIFO/pipe
ERR_FS_CP_NON_DIR_TO_DIR Cannot copy non-directory to directory
ERR_FS_CP_SOCKET Cannot copy socket
ERR_FS_CP_SYMLINK_TO_SUBDIRECTORY Symlink target is subdirectory of source
ERR_FS_CP_UNKNOWN Unknown file type during copy
ERR_ACCESS_DENIED Permission denied (permission model)

Network Errors:

Code Description
ERR_SOCKET_ALREADY_BOUND Socket already bound to address
ERR_SOCKET_BAD_BUFFER_SIZE Invalid buffer size
ERR_SOCKET_BAD_PORT Port must be ≥ 0 and < 65536
ERR_SOCKET_BAD_TYPE Invalid socket type
ERR_SOCKET_BUFFER_SIZE Buffer size error
ERR_SOCKET_CLOSED Socket is closed
ERR_SOCKET_CLOSED_BEFORE_CONNECTION Socket closed before connection established
ERR_SOCKET_CONNECTION_TIMEOUT Socket connection timed out
ERR_SOCKET_DGRAM_IS_CONNECTED Datagram socket already connected
ERR_SOCKET_DGRAM_NOT_CONNECTED Datagram socket not connected
ERR_SOCKET_DGRAM_NOT_RUNNING Datagram socket not running
ERR_SERVER_ALREADY_LISTEN Server already listening
ERR_SERVER_NOT_RUNNING Server not running

HTTP Errors:

Code Description
ERR_HTTP_HEADERS_SENT Headers already sent
ERR_HTTP_INVALID_HEADER_VALUE Invalid HTTP header value
ERR_HTTP_INVALID_STATUS_CODE Invalid HTTP status code
ERR_HTTP_REQUEST_TIMEOUT HTTP request timed out
ERR_HTTP_SOCKET_ENCODING Socket encoding error
ERR_HTTP_TRAILER_INVALID Invalid trailer
ERR_HTTP2_CONNECT_AUTHORITY HTTP/2 CONNECT authority missing
ERR_HTTP2_CONNECT_PATH HTTP/2 CONNECT path forbidden
ERR_HTTP2_CONNECT_SCHEME HTTP/2 CONNECT scheme forbidden
ERR_HTTP2_ERROR General HTTP/2 error
ERR_HTTP2_GOAWAY_SESSION HTTP/2 session received GOAWAY
ERR_HTTP2_HEADERS_AFTER_RESPOND HTTP/2 headers after response started
ERR_HTTP2_HEADERS_SENT HTTP/2 headers already sent
ERR_HTTP2_INVALID_CONNECTION_HEADERS HTTP/2 connection-specific headers invalid
ERR_HTTP2_INVALID_HEADER_VALUE Invalid HTTP/2 header value
ERR_HTTP2_INVALID_INFO_STATUS Invalid HTTP/2 informational status
ERR_HTTP2_INVALID_ORIGIN Invalid HTTP/2 origin
ERR_HTTP2_INVALID_PACKED_SETTINGS_LENGTH Invalid packed settings length
ERR_HTTP2_INVALID_PSEUDOHEADER Invalid HTTP/2 pseudo-header
ERR_HTTP2_INVALID_SESSION HTTP/2 session invalid
ERR_HTTP2_INVALID_SETTING_VALUE Invalid HTTP/2 setting value
ERR_HTTP2_INVALID_STREAM Invalid HTTP/2 stream
ERR_HTTP2_MAX_PENDING_SETTINGS_ACK Too many pending HTTP/2 settings
ERR_HTTP2_NESTED_PUSH Nested HTTP/2 push
ERR_HTTP2_NO_MEM HTTP/2 out of memory
ERR_HTTP2_NO_SOCKET_MANIPULATION HTTP/2 socket manipulation forbidden
ERR_HTTP2_ORIGIN_LENGTH HTTP/2 origin length exceeded
ERR_HTTP2_OUT_OF_STREAMS HTTP/2 out of streams
ERR_HTTP2_PAYLOAD_FORBIDDEN HTTP/2 payload forbidden for method
ERR_HTTP2_PING_CANCEL HTTP/2 ping cancelled
ERR_HTTP2_PING_LENGTH HTTP/2 ping length invalid
ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED HTTP/2 pseudo-header not allowed
ERR_HTTP2_PUSH_DISABLED HTTP/2 push disabled
ERR_HTTP2_SEND_FILE HTTP/2 send file error
ERR_HTTP2_SEND_FILE_NOSEEK HTTP/2 cannot seek file
ERR_HTTP2_SESSION_ERROR HTTP/2 session error
ERR_HTTP2_SETTINGS_CANCEL HTTP/2 settings cancelled
ERR_HTTP2_SOCKET_BOUND HTTP/2 socket already bound
ERR_HTTP2_SOCKET_UNBOUND HTTP/2 socket unbound
ERR_HTTP2_STATUS_101 HTTP/2 status 101 not allowed
ERR_HTTP2_STATUS_INVALID Invalid HTTP/2 status code
ERR_HTTP2_STREAM_CANCEL HTTP/2 stream cancelled
ERR_HTTP2_STREAM_ERROR HTTP/2 stream error
ERR_HTTP2_STREAM_SELF_DEPENDENCY HTTP/2 stream self-dependency
ERR_HTTP2_TOO_MANY_CUSTOM_SETTINGS Too many custom HTTP/2 settings
ERR_HTTP2_TOO_MANY_INVALID_FRAMES Too many invalid HTTP/2 frames
ERR_HTTP2_TRAILERS_ALREADY_SENT HTTP/2 trailers already sent
ERR_HTTP2_TRAILERS_NOT_READY HTTP/2 trailers not ready
ERR_HTTP2_UNSUPPORTED_PROTOCOL Unsupported HTTP/2 protocol

Crypto Errors:

Code Description
ERR_CRYPTO_CUSTOM_ENGINE_NOT_SUPPORTED Custom OpenSSL engine not supported
ERR_CRYPTO_ECDH_INVALID_FORMAT Invalid ECDH format
ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY Invalid ECDH public key
ERR_CRYPTO_ENGINE_UNKNOWN Unknown crypto engine
ERR_CRYPTO_FIPS_FORCED FIPS mode forced but cannot be enabled
ERR_CRYPTO_FIPS_UNAVAILABLE FIPS not available
ERR_CRYPTO_HASH_FINALIZED Hash already finalized
ERR_CRYPTO_HASH_UPDATE_FAILED Hash update failed
ERR_CRYPTO_INCOMPATIBLE_KEY Incompatible key for operation
ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS Incompatible key options
ERR_CRYPTO_INITIALIZATION_FAILED Crypto initialization failed
ERR_CRYPTO_INVALID_AUTH_TAG Invalid authentication tag
ERR_CRYPTO_INVALID_COUNTER Invalid counter
ERR_CRYPTO_INVALID_CURVE Invalid elliptic curve
ERR_CRYPTO_INVALID_DIGEST Invalid digest algorithm
ERR_CRYPTO_INVALID_IV Invalid initialization vector
ERR_CRYPTO_INVALID_JWK Invalid JSON Web Key
ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE Invalid key object type
ERR_CRYPTO_INVALID_KEYLEN Invalid key length
ERR_CRYPTO_INVALID_KEYPAIR Invalid key pair
ERR_CRYPTO_INVALID_MESSAGELEN Invalid message length
ERR_CRYPTO_INVALID_SCRYPT_PARAMS Invalid scrypt parameters
ERR_CRYPTO_INVALID_STATE Invalid crypto state
ERR_CRYPTO_INVALID_TAG_LENGTH Invalid tag length
ERR_CRYPTO_JOB_INIT_FAILED Crypto job initialization failed
ERR_CRYPTO_JWK_UNSUPPORTED_CURVE Unsupported JWK curve
ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE Unsupported JWK key type
ERR_CRYPTO_OPERATION_FAILED Crypto operation failed
ERR_CRYPTO_PBKDF2_ERROR PBKDF2 error
ERR_CRYPTO_SCRYPT_INVALID_PARAMETER Invalid scrypt parameter
ERR_CRYPTO_SCRYPT_NOT_SUPPORTED Scrypt not supported
ERR_CRYPTO_SIGN_KEY_REQUIRED Sign key required
ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH Buffers must be same length for timingSafeEqual
ERR_CRYPTO_UNKNOWN_CIPHER Unknown cipher algorithm
ERR_CRYPTO_UNKNOWN_DH_GROUP Unknown DH group
ERR_CRYPTO_UNSUPPORTED_OPERATION Unsupported crypto operation

Stream Errors:

Code Description
ERR_STREAM_ALREADY_FINISHED Stream write after end
ERR_STREAM_CANNOT_PIPE Cannot pipe from this stream
ERR_STREAM_DESTROYED Stream was destroyed
ERR_STREAM_NULL_VALUES Null values cannot be written to stream
ERR_STREAM_PREMATURE_CLOSE Stream closed prematurely
ERR_STREAM_PUSH_AFTER_EOF Push after EOF
ERR_STREAM_UNSHIFT_AFTER_END_EVENT Unshift after end event
ERR_STREAM_WRAP Stream wrapping error
ERR_STREAM_WRITE_AFTER_END Write after end

Worker Thread Errors:

Code Description
ERR_WORKER_INIT_FAILED Worker initialization failed
ERR_WORKER_INVALID_EXEC_ARGV Invalid worker exec argv
ERR_WORKER_NOT_RUNNING Worker is not running
ERR_WORKER_OUT_OF_MEMORY Worker ran out of memory
ERR_WORKER_PATH Invalid worker file path
ERR_WORKER_UNSERIALIZABLE_ERROR Error cannot be serialized for transfer
ERR_WORKER_UNSUPPORTED_EXTENSION Unsupported file extension for worker
ERR_WORKER_UNSUPPORTED_OPERATION Unsupported operation in worker

TLS/SSL Errors:

Code Description
ERR_TLS_CERT_ALTNAME_FORMAT Invalid certificate altname format
ERR_TLS_CERT_ALTNAME_INVALID Certificate hostname mismatch
ERR_TLS_DH_PARAM_SIZE DH parameter size too small
ERR_TLS_HANDSHAKE_TIMEOUT TLS handshake timed out
ERR_TLS_INVALID_CONTEXT Invalid TLS context
ERR_TLS_INVALID_PROTOCOL_METHOD Invalid TLS protocol method
ERR_TLS_INVALID_PROTOCOL_VERSION Invalid TLS protocol version
ERR_TLS_INVALID_STATE Invalid TLS state
ERR_TLS_PROTOCOL_VERSION_CONFLICT TLS protocol version conflict
ERR_TLS_PSK_SET_IDENTITY_HINT_FAILED Failed to set PSK identity hint
ERR_TLS_RENEGOTIATION_DISABLED TLS renegotiation disabled
ERR_TLS_REQUIRED_SERVER_NAME Server name required for TLS
ERR_TLS_SESSION_ATTACK TLS session renegotiation attack detected
ERR_TLS_SNI_FROM_SERVER SNI from server (unexpected)

Encoding Errors:

Code Description
ERR_ENCODING_INVALID_ENCODED_DATA Invalid encoded data
ERR_ENCODING_NOT_SUPPORTED Encoding not supported
ERR_UNKNOWN_ENCODING Unknown encoding name

VM (Virtual Machine) Errors:

Code Description
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING Dynamic import callback not set
ERR_VM_MODULE_ALREADY_LINKED Module already linked
ERR_VM_MODULE_CACHED_DATA_REJECTED Cached data rejected
ERR_VM_MODULE_CANNOT_CREATE_CACHED_DATA Cannot create cached data
ERR_VM_MODULE_DIFFERENT_CONTEXT Module from different context
ERR_VM_MODULE_LINK_FAILURE Module link failure
ERR_VM_MODULE_LINKING_ERRORED Module linking errored
ERR_VM_MODULE_NOT_MODULE Not a module
ERR_VM_MODULE_STATUS Invalid module status

Assertion and Validation Errors:

Code Description
ERR_ASSERTION Assertion failed
ERR_AMBIGUOUS_ARGUMENT Ambiguous argument
ERR_INCOMPATIBLE_OPTION_PAIR Incompatible option pair
ERR_INVALID_RETURN_PROPERTY Invalid return property
ERR_INVALID_RETURN_PROPERTY_VALUE Invalid return property value
ERR_INVALID_RETURN_VALUE Invalid return value
ERR_INVALID_STATE Invalid state for operation
ERR_INVALID_URL Invalid URL
ERR_INVALID_URL_SCHEME Invalid URL scheme

Permission Model Errors:

Code Description
ERR_ACCESS_DENIED Operation denied by permission model
ERR_MANIFEST_ASSERT_INTEGRITY Module integrity check failed (policy)
ERR_MANIFEST_DEPENDENCY_MISSING Manifest dependency missing
ERR_MANIFEST_INTEGRITY_MISMATCH Manifest integrity mismatch
ERR_MANIFEST_INVALID_RESOURCE_FIELD Invalid manifest resource field
ERR_MANIFEST_INVALID_SPECIFIER Invalid manifest specifier
ERR_MANIFEST_PARSE_POLICY Cannot parse policy manifest
ERR_MANIFEST_TDZ Manifest temporal dead zone
ERR_MANIFEST_UNKNOWN_ONERROR Unknown manifest onError action

Miscellaneous Errors:

Code Description
ERR_BUFFER_CONTEXT_NOT_AVAILABLE Buffer context not available
ERR_BUFFER_OUT_OF_BOUNDS Buffer access out of bounds
ERR_BUFFER_TOO_LARGE Buffer exceeds maximum length
ERR_CANNOT_WATCH_SIGINT Cannot watch SIGINT
ERR_CHILD_CLOSED_BEFORE_REPLY Child closed before reply
ERR_CHILD_PROCESS_IPC_REQUIRED IPC channel required
ERR_CHILD_PROCESS_STDIO_MAXBUFFER MaxBuffer exceeded
ERR_CONSOLE_WRITABLE_STREAM Console writable stream error
ERR_CONSTRUCT_CALL_INVALID Constructor call invalid
ERR_CONSTRUCT_CALL_REQUIRED Constructor call required
ERR_CONTEXT_NOT_INITIALIZED Context not initialized
ERR_DEBUGGER_ERROR Debugger error
ERR_DEBUGGER_STARTUP_ERROR Debugger startup error
ERR_DIR_CLOSED Directory handle closed
ERR_DIR_CONCURRENT_OPERATION Concurrent directory operation
ERR_DNS_SET_SERVERS_FAILED DNS set servers failed
ERR_DOMAIN_CALLBACK_NOT_AVAILABLE Domain callback not available
ERR_DOMAIN_CANNOT_SET_UNCAUGHT_EXCEPTION_CAPTURE Domain conflict with uncaughtException capture
ERR_DUPLICATE_STARTUP_SNAPSHOT_MAIN_FUNCTION Duplicate snapshot main function
ERR_EVAL_ESM_CANNOT_PRINT Cannot print ESM eval result
ERR_EVENT_RECURSION Event recursion detected
ERR_FEATURE_UNAVAILABLE_ON_PLATFORM Feature unavailable on this platform
ERR_ILLEGAL_CONSTRUCTOR Constructor is not callable
ERR_IMPORT_ASSERTION_TYPE_FAILED Import assertion type check failed
ERR_IMPORT_ASSERTION_TYPE_MISSING Import assertion type missing
ERR_IMPORT_ASSERTION_TYPE_UNSUPPORTED Unsupported import assertion type
ERR_IMPORT_ATTRIBUTE_MISSING Import attribute missing
ERR_IMPORT_ATTRIBUTE_TYPE_INCOMPATIBLE Import attribute type incompatible
ERR_IMPORT_ATTRIBUTE_UNSUPPORTED Unsupported import attribute
ERR_INPUT_TYPE_NOT_ALLOWED Input type not allowed
ERR_INSPECTOR_ALREADY_ACTIVATED Inspector already activated
ERR_INSPECTOR_ALREADY_CONNECTED Inspector already connected
ERR_INSPECTOR_CLOSED Inspector session closed
ERR_INSPECTOR_COMMAND Inspector command error
ERR_INSPECTOR_NOT_ACTIVE Inspector not active
ERR_INSPECTOR_NOT_AVAILABLE Inspector not available
ERR_INSPECTOR_NOT_CONNECTED Inspector not connected
ERR_INSPECTOR_NOT_WORKER Inspector not in worker
ERR_INTERNAL_ASSERTION Internal assertion (Node.js bug)
ERR_IPC_CHANNEL_CLOSED IPC channel closed
ERR_IPC_DISCONNECTED IPC disconnected
ERR_IPC_ONE_PIPE Only one IPC pipe allowed
ERR_IPC_SYNC_FORK Synchronous fork with IPC
ERR_LOADER_CHAIN_INCOMPLETE Loader chain incomplete
ERR_METHOD_NOT_IMPLEMENTED Method not implemented
ERR_MISSING_OPTION Required option missing
ERR_MISSING_TRANSFERABLE_IN_TRANSFER_LIST Missing transferable in transfer list
ERR_MULTIPLE_CALLBACK Callback called multiple times
ERR_NAPI_CONS_FUNCTION N-API constructor function error
ERR_NAPI_CONS_PROTOTYPE_OBJECT N-API constructor prototype error
ERR_NAPI_INVALID_DATAVIEW_ARGS Invalid N-API DataView arguments
ERR_NAPI_INVALID_TYPEDARRAY_ALIGNMENT Invalid N-API TypedArray alignment
ERR_NAPI_INVALID_TYPEDARRAY_LENGTH Invalid N-API TypedArray length
ERR_NAPI_TSFN_CALL_JS N-API TSFN call JS error
ERR_NAPI_TSFN_GET_UNDEFINED N-API TSFN get undefined error
ERR_NAPI_TSFN_START_IDLE_LOOP N-API TSFN idle loop start error
ERR_NAPI_TSFN_STOP_IDLE_LOOP N-API TSFN idle loop stop error
ERR_NOT_BUILDING_SNAPSHOT Not building snapshot
ERR_NOT_IN_SINGLE_EXECUTABLE_APPLICATION Not in a SEA
ERR_NOT_SUPPORTED_IN_SNAPSHOT Not supported in snapshot
ERR_OPERATION_FAILED Operation failed
ERR_OUTOFMEMORY Out of memory
ERR_PARSE_ARGS_INVALID_OPTION_VALUE Invalid parseArgs option value
ERR_PARSE_ARGS_UNEXPECTED_POSITIONAL Unexpected positional argument
ERR_PARSE_ARGS_UNKNOWN_OPTION Unknown parseArgs option
ERR_PERFORMANCE_INVALID_TIMESTAMP Invalid performance timestamp
ERR_PERFORMANCE_MEASURE_INVALID_OPTIONS Invalid performance measure options
ERR_QUIC_CONNECTION_FAILED QUIC connection failed
ERR_QUIC_ENDPOINT_CLOSED QUIC endpoint closed
ERR_QUIC_OPEN_STREAM_FAILED QUIC stream open failed
ERR_QUIC_TRANSPORT_ERROR QUIC transport error
ERR_SCRIPT_EXECUTION_INTERRUPTED Script execution interrupted
ERR_SCRIPT_EXECUTION_TIMEOUT Script execution timed out
ERR_SINGLE_EXECUTABLE_APPLICATION_ASSET_NOT_FOUND SEA asset not found
ERR_SQLITE_ERROR SQLite error
ERR_TEST_FAILURE Test failure
ERR_UNAVAILABLE_DURING_EXIT Unavailable during process exit
ERR_UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SET Uncaught exception capture already set
ERR_UNESCAPED_CHARACTERS Unescaped characters in string
ERR_UNHANDLED_REJECTION Unhandled promise rejection
ERR_UNKNOWN_BUILTIN_MODULE Unknown built-in module
ERR_UNKNOWN_CREDENTIAL Unknown credential
ERR_UNKNOWN_SIGNAL Unknown signal name
ERR_USE_AFTER_CLOSE Use after close
ERR_VALID_PERFORMANCE_ENTRY_TYPE Valid performance entry type required
ERR_WASI_ALREADY_STARTED WASI already started
ERR_WASI_NOT_STARTED WASI not started
ERR_ZLIB_INITIALIZATION_FAILED Zlib initialization failed

8.6 Key Classes

Class Module Description
AbortController lib/internal/abort_controller.js Web API: control abort signals for cancellable operations
AbortSignal lib/internal/abort_controller.js Web API: signal for aborting async operations
Blob lib/internal/blob.js Web API: immutable raw data container
File lib/internal/file.js Web API: file metadata + blob data
BlockList lib/net.js IP address block list for access control
FastBuffer lib/internal/buffer.js Optimized Buffer subclass of Uint8Array
TextEncoder lib/internal/encoding.js Web API: string → UTF-8 bytes
TextDecoder lib/internal/encoding.js Web API: bytes → string (multiple encodings)
URL lib/internal/url.js WHATWG URL parser (wraps ada C++ library)
URLSearchParams lib/internal/url.js URL query parameter manipulation
Worker lib/internal/worker.js Worker thread management
Event lib/internal/event_target.js Web API: base event class
EventTarget lib/internal/event_target.js Web API: event dispatch target
NodeEventTarget lib/internal/event_target.js Hybrid EventTarget + EventEmitter
Histogram lib/internal/histogram.js Statistical histogram (percentiles, min, max, mean)
MIMEType lib/internal/mime.js MIME type parsing and manipulation
MIMEParams lib/internal/mime.js MIME type parameters
Navigator lib/internal/navigator.js Web API: limited navigator (hardwareConc, language)
SocketAddress lib/internal/socketaddress.js IP address + port encapsulation
Timeout lib/internal/timers.js setTimeout/setInterval handle
Immediate lib/internal/timers.js setImmediate handle
Lock lib/internal/locks.js Web Locks API: named lock
LockManager lib/internal/locks.js Web Locks API: lock coordination
HeapSnapshotStream lib/internal/heap_utils.js Readable stream of V8 heap snapshot data
Control lib/internal/child_process.js Internal child process control
ReadableStream lib/internal/webstreams/ Web Streams API: readable stream
WritableStream lib/internal/webstreams/ Web Streams API: writable stream
TransformStream lib/internal/webstreams/ Web Streams API: transform stream

8.7 Code Patterns and Conventions

Primordials

Node.js protects against prototype pollution by capturing built-in functions at startup:

// lib/internal/per_context/primordials.js captures everything:
const {
  ArrayPrototypeMap,
  ObjectDefineProperty,
  StringPrototypeSlice,
  PromisePrototypeThen,
  SafeMap,
  SafeSet,
  SafeWeakMap,
} = primordials;

// Usage in internal modules — never call Array.prototype.map directly
const result = ArrayPrototypeMap(items, transform);

This prevents user code from breaking Node.js internals by modifying Array.prototype.map, Object.keys, etc.

Internal Bindings

C++ modules are exposed to JavaScript via internalBinding():

// In lib/internal/crypto/hash.js
const { Hash: _Hash } = internalBinding('crypto');
// _Hash is a C++ class from src/crypto/crypto_hash.cc

Public modules use process.binding() (deprecated) or internalBinding() (internal only, not accessible from user code).

Lazy Loading

Expensive modules are loaded on first use:

let crypto;
function getCrypto() {
  if (crypto === undefined) {
    crypto = require('crypto');
  }
  return crypto;
}

Validators

lib/internal/validators.js provides standardized argument validation:

const {
  validateFunction,
  validateInteger,
  validateObject,
  validateString,
  validateBoolean,
  validateAbortSignal,
  validateBuffer,
  validateEncoding,
  validatePort,
} = require('internal/validators');

// Usage
function myFunction(path, options) {
  validateString(path, 'path');
  validateObject(options, 'options');
  validateInteger(options.timeout, 'options.timeout', 0);
}

8.8 Testing Infrastructure

The test suite contains 4,000+ test files organized by category:

Category Directory File Count Description
parallel test/parallel/ 3,929 Standard tests that run in parallel
sequential test/sequential/ 111 Tests requiring exclusive execution
pseudo-tty test/pseudo-tty/ 40 Tests requiring a pseudo-terminal
async-hooks test/async-hooks/ 98 Async hooks lifecycle tests
es-module test/es-module/ 97 ECMAScript module system tests
pummel test/pummel/ 64 Stress tests (heavy I/O, memory)
embedding test/embedding/ 14 Node.js embedding API tests
addons test/addons/ ~100+ C++ addon tests (old API)
node-api test/node-api/ ~100+ Node-API (N-API) native addon tests
sea test/sea/ 37 Single Executable Application tests
wasi test/wasi/ 27 WebAssembly System Interface tests
ffi test/ffi/ 10 Foreign Function Interface tests
known_issues test/known_issues/ 24 Tests for known unfixed bugs
cctest test/cctest/ varies C++ unit tests (googletest)
wasm test/wasm/ varies WebAssembly tests
internet test/internet/ varies Tests requiring internet access
tick-processor test/tick-processor/ varies V8 tick processor tests
message test/message/ varies Expected output message tests
fixtures test/fixtures/ varies Shared test fixtures and data
common test/common/ varies Shared test utilities and helpers

Running Tests

# Run all tests
make test

# Run parallel tests only
make test-parallel

# Run a specific test
python3 tools/test.py test/parallel/test-http-server.js

# Run with verbose output
python3 tools/test.py -v test/parallel/test-http-server.js

# Run linting
make lint
make lint-js    # JavaScript only
make lint-cpp   # C++ only
make lint-md    # Markdown only

# Run C++ tests
make cctest

# Run with code coverage
make coverage

# Run benchmarks
make bench

8.9 Contributing — Build and Test Workflow

# 1. Clone and build
git clone https://github.com/nodejs/node.git
cd node
./configure --ninja
ninja -C out/Release -j$(nproc)

# 2. Run tests
make test

# 3. After making changes, run affected tests
python3 tools/test.py test/parallel/test-your-feature.js

# 4. Lint
make lint

# 5. Generate documentation
make doc

9. Integration Points

9.1 Node-API (N-API)

Node-API is the stable ABI for building native addons that work across Node.js versions without recompilation:

// addon.c
#include <node_api.h>

napi_value MyFunction(napi_env env, napi_callback_info info) {
  napi_value result;
  napi_create_string_utf8(env, "hello from C", NAPI_AUTO_LENGTH, &result);
  return result;
}

napi_value Init(napi_env env, napi_value exports) {
  napi_property_descriptor desc = {
    "myFunction", NULL, MyFunction, NULL, NULL, NULL, napi_default, NULL
  };
  napi_define_properties(env, exports, 1, &desc);
  return exports;
}

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
// Usage
const addon = require('./build/Release/addon.node');
console.log(addon.myFunction()); // "hello from C"

Node-API tests live in test/node-api/ and exercise all API surface areas. The API is versioned (currently up to version 9+), with each version adding new functions while maintaining backward compatibility.

9.2 V8 Embedding API

Node.js can be embedded in other C++ applications:

#include "node.h"
#include "uv.h"

int main(int argc, char* argv[]) {
  // Initialize Node.js
  std::vector<std::string> args(argv, argv + argc);
  std::unique_ptr<node::InitializationResult> result =
      node::InitializeOncePerProcess(args);

  // Create isolate and environment
  node::EmbedderSnapshotData::Pointer snapshot;
  v8::Isolate* isolate = node::NewIsolate(
      node::CreateArrayBufferAllocator(), &loop, platform.get());

  // Run Node.js event loop
  node::LoadEnvironment(env, "const http = require('http');"
                             "http.createServer((req, res) => {"
                             "  res.end('embedded');"
                             "}).listen(3000);");

  // Spin the event loop
  node::SpinEventLoop(env).FromJust();

  // Cleanup
  node::Stop(env);
  return 0;
}

Embedding tests are in test/embedding/ (14 test files).

9.3 Foreign Function Interface (FFI)

Experimental FFI allows calling native shared library functions without compiling a native addon:

// Experimental — requires --experimental-permission and --allow-ffi
import { dlopen, FFIType } from 'node:ffi';

const lib = dlopen('libm.so.6', {
  ceil: {
    args: [FFIType.f64],
    returns: FFIType.f64,
  },
});

console.log(lib.symbols.ceil(1.2)); // 2

The FFI implementation is minimal (2 files, 2.6K chars in src/) and wraps libffi. Tests are in test/ffi/ (10 files).

9.4 WASI (WebAssembly System Interface)

WASI provides a sandboxed system interface for WebAssembly modules:

import { readFile } from 'node:fs/promises';
import { WASI } from 'node:wasi';

const wasi = new WASI({
  version: 'preview1',
  args: process.argv,
  env: process.env,
  preopens: {
    '/sandbox': '/tmp/wasi-sandbox'
  }
});

const wasm = await WebAssembly.compile(await readFile('./module.wasm'));
const instance = await WebAssembly.instantiate(wasm, wasi.getImportObject());
wasi.start(instance);

WASI tests are in test/wasi/ (27 files). The implementation wraps uvwasi (in deps).

9.5 Inspector Protocol (CDP)

The Chrome DevTools Protocol enables programmatic debugging, profiling, and automation:

import inspector from 'node:inspector/promises';

const session = new inspector.Session();
session.connect();

// Take heap snapshot
await session.post('HeapProfiler.takeHeapSnapshot');

// Enable CPU profiler
await session.post('Profiler.enable');
await session.post('Profiler.start');
// ... run workload ...
const { profile } = await session.post('Profiler.stop');

// Evaluate expressions
const { result } = await session.post('Runtime.evaluate', {
  expression: 'process.memoryUsage()'
});

session.disconnect();

The inspector can also be accessed over WebSocket (port 9229 by default) for remote debugging with Chrome DevTools, VS Code, or any CDP-compatible client.

9.6 Diagnostics Channel

Named publish/subscribe channels for instrumenting Node.js core and third-party modules:

import diagnostics_channel from 'node:diagnostics_channel';

// Subscribe to HTTP request events
const channel = diagnostics_channel.channel('http.client.request.start');
channel.subscribe((message) => {
  console.log('HTTP request:', message.request.method, message.request.path);
});

// Built-in channels include:
// http.client.request.start / .error
// http.client.response.finish
// http.server.request.start / .error
// http.server.response.finish
// net.client.socket / net.server.socket
// worker_threads (various)
// module.require.start / .end
// module.import.start / .end

Note

Diagnostics channels have near-zero overhead when no subscribers are attached. They are the recommended way to instrument Node.js applications for monitoring and tracing, replacing monkey-patching approaches used by older APM tools.