Networking in Node.js
Node was built for the network. Its non-blocking, event-driven core (the same event loop and streams you've already met) is exactly what makes it excel at handling thousands of simultaneous connections on a single thread. Before diving into HTTP, it pays to understand the layers underneath it — TCP, UDP, and DNS — and the small family of core modules Node provides for each.
The networking stack, briefly
Network communication is layered. Each Node module maps onto a layer, and the higher-level ones are built on the lower:
Layer | What it does | Node module |
|---|---|---|
Application | HTTP, WebSocket, your protocol |
|
Transport | Reliable streams (TCP) / datagrams (UDP) |
|
Naming | Hostnames → IP addresses |
|
Network/Link | IP routing, Ethernet | (handled by the OS) |
TCP vs UDP — the fundamental choice
TCP ( | UDP ( | |
|---|---|---|
Connection | Connection-oriented (handshake first) | Connectionless (just send) |
Reliability | Guaranteed delivery, retransmits | Best-effort — packets can drop |
Ordering | In-order, byte stream | No ordering guarantee |
Overhead | Higher (acks, state) | Minimal |
Model | A continuous stream of bytes | Discrete independent packets |
Use for | HTTP, databases, anything needing correctness | Video/voice, gaming, DNS, metrics |
Why Node handles concurrency so well here
A traditional thread-per-connection server spends most threads blocked waiting on slow network I/O. Node instead registers a non-blocking socket with the OS and gets an event when data is ready — so one thread juggles tens of thousands of mostly-idle connections. This is the non-blocking I/O model applied to the network, and it's Node's original reason for being.
The modules this section covers
TCP servers & clients (
net) — the reliable byte-stream transport beneath HTTP, with sockets as duplex streams.UDP sockets (
dgram) — connectionless datagrams for low-latency, loss-tolerant data.DNS lookups (
dns) — resolving hostnames to IP addresses, and the resolve-vs-lookup distinction.
After these, the HTTP section builds the web server you probably came for — but now you'll know what's happening one layer down.
A taste: an echo server in 6 lines
import { createServer } from 'node:net'
// A TCP server that echoes back whatever it receives:
createServer((socket) => {
socket.write('Welcome!\n')
socket.pipe(socket) // pipe input straight back to output
}).listen(4000, () => console.log('echo server on :4000'))