Node.js, part 23: Node 22 — WebSocket client, glob, and magic bytes
Part 23from the Node.js series · 24 parts in all
Node 22 reads like a release that went through the dependency list of an ordinary service
and moved half of it into core. A WebSocket client, a glob implementation, a file watcher, and
the node --run script runner all shipped — each one retiring a very popular
package. Part 23 is what they replace and how to use them.
A WebSocket client, no ws dependency
const ws = new WebSocket('wss://example.com/feed');
ws.onopen = () => ws.send(JSON.stringify({ subscribe: 'prices' }));
ws.onmessage = (event) => console.log(JSON.parse(event.data));
ws.onerror = (err) => console.error('socket error', err.message);
// Closing cleanly, which is the part hand-rolled clients get wrong.
ws.close(1000, 'done');
The API is the browser's, which is the same argument as fetch in part 16: one
piece of knowledge, two runtimes. Reconnection, backoff, and heartbeats are still yours — a
socket library is not a resilience library.
glob and watch, in core
const { glob } = require('node:fs/promises');
const { watch } = require('node:fs');
const tests = await glob('src/**/*.{test,spec}.{js,ts}');
// Cross-platform recursive watch: no chokidar, no fsevents build step.
for await (const event of watch('src', { recursive: true })) {
console.log(event.eventType, event.filename);
}
That second block is the one that removes a native dependency from a lot of toolchains —
chokidar existed largely because recursive watching was unreliable, and the
platform support is now good enough for core to expose it.
Smaller things worth knowing
node --run <script>runs apackage.jsonscript directly, without npm's startup cost or its argument handling quirks — noticeably faster for repeated runs.import.meta.dirnamefinally gives an ES module its own directory, retiring thefileURLToPathincantation from part 5.- V8 12.4 brings the standard library closer to the browser's, which mostly means fewer surprises when code moves between them.
Across parts 16, 22 and 23 the pattern is the same: the platform absorbed the packages everyone was installing, and the reasonable dependency list for a Node service became visibly shorter than it was in 2018. Next: the last dependency worth removing — the one that runs your logging and shutdown.