Node 21 brings built-in WebSocket support
Node has shipped a built-in WebSocket client. It landed experimentally in Node 21 (October 2023), graduated to stable in Node 22 LTS, and in 2026 is just part of the runtime — Node 22 is Active LTS, Node 24 is Maintenance LTS, and globalThis.WebSocket works in both without a flag.
What that means in practice: you can connect to a WebSocket server without installing ws.
1const ws = new WebSocket('wss://example.com/socket')
2
3ws.addEventListener('open', () => ws.send('hello'))
4ws.addEventListener('message', (e) => console.log(e.data))Same API your browser code uses. No import, no dependency, no version-skew between client and server libraries.
What's built in, what isn't
The thing that confused me when I first read the Node 21 release notes is that "WebSocket support" only refers to the client.
| Capability | Node 22+ | Bun | Deno |
|---|---|---|---|
WebSocket client (new WebSocket) | ✓ | ✓ | ✓ |
| WebSocket server | needs ws or uWebSockets.js | Bun.serve({ websocket }) | Deno.upgradeWebSocket |
If you're building anything that accepts WebSocket connections in Node, you still reach for ws — that hasn't changed. Bun and Deno have the upgrade primitive baked into their HTTP server APIs, which is the actual gap Node hasn't closed.
When the built-in client matters
Mostly it matters for code that wasn't worth pulling in ws for: a one-off subscription to a market data feed, a small CLI that talks to a dev tool, an MCP server connecting to a remote transport. You drop a new WebSocket(url), get the same event-emitter shape fetch already gave you, and ship.
For full duplex services it's a nice-to-have. For glue code it's a real win.