Technology handbook
Node.js — Runtime, APIs, Streams & Operations
Server-side JavaScript with the event loop, modules, streams, HTTP, processes and production operations.
- Topics
- 20
- Sections
- 6
Runtime foundations
Event loop
Understand how Node schedules timers, I/O callbacks, microtasks and CPU work.
- Timers, I/O callbacks and microtasks run in phases, not in the order they were written.
- Microtasks drain fully between phases, so a promise chain can starve I/O.
- A CPU-bound function blocks every phase, because there is one thread doing all of it.
EventEmitter
Publish and subscribe to events while managing listener lifetime and errors.
- Events are published and subscribed to, with listener lifetime managed.
- A listener never removed is a leak that grows with every subscription.
- An error event with no listener throws instead of being ignored.
Worker threads
Move CPU-bound JavaScript to worker threads without blocking the event loop.
- CPU-bound JavaScript moves off the thread that serves requests.
- Each worker has its own heap, so data is copied or shared deliberately.
- Spawning one per task costs more than the work for anything small.
Modules
ES modules and imports
Choose module boundaries and import syntax that match Node and your package configuration.
- The module system is decided by the package type field and the file extension.
- Imports are resolved statically, so a specifier cannot be built at runtime.
- Top-level await is available here and is not in CommonJS.
CommonJS and package exports
Bridge require and import while defining explicit package entry points.
- require and import interoperate, with entry points declared explicitly.
- The exports field is what makes internal files genuinely private.
- A default export does not cross the two systems the way it appears to.
npm and dependency management
Keep package scripts, lockfiles and dependency boundaries reproducible.
- Scripts, lockfiles and dependency boundaries stay reproducible.
- The lockfile is what makes two installs produce the same tree.
- A dependency only needed to build belongs in devDependencies, not in the runtime.
Networking
HTTP servers
Handle requests, responses, headers, status codes and streaming bodies explicitly.
- Requests, responses, headers and status codes are handled explicitly.
- The body is a stream, so it does not exist until it is read.
- A response that is never ended leaves the client waiting until it times out.
HTTP fetch
Make outbound requests with timeouts, abort signals and explicit response checks.
- Outbound requests carry timeouts, abort signals and checked responses.
- fetch does not reject on a 404 or a 500, so the status must be read.
- Without a signal, a hung request holds the caller indefinitely.
WebSocket servers
Maintain real-time connections while handling backpressure and disconnects.
- Real-time connections are maintained through backpressure and disconnects.
- A connection can vanish without a close frame, so heartbeats detect it.
- Slow clients need their send buffer bounded or memory grows per socket.
Operations
Process errors and signals
Handle failures, shutdown signals and exit behavior without hiding operational problems.
- Failures, shutdown signals and exit codes are handled rather than hidden.
- An unhandled rejection terminates the process by default in modern Node.
- Swallowing an error to keep the process alive leaves it in an unknown state.
Diagnostics and logging
Emit structured logs and inspect memory, CPU and event-loop behavior in production.
- Structured logs, memory, CPU and event-loop behaviour are observable in production.
- Event-loop delay is the measurement that reveals blocking work.
- Logging to stdout synchronously makes logging itself a bottleneck.
Graceful shutdown
Stop accepting work, drain connections and exit cleanly on deployment signals.
- The process stops accepting work, drains connections and exits cleanly.
- Keep-alive connections hold the server open unless they are closed deliberately.
- Exiting immediately on a signal drops requests that were mid-flight.