What Is New in Node.js 19?
| Category | Change |
|---|---|
| New Features | HTTP keep-alive enabled by default for all HTTP clients |
| New Features | --watch mode for auto-restarting on file changes (experimental) |
| New Features | WebCrypto API upgraded to stable |
| Improvements | V8 10.7 with Intl.NumberFormat v3 |
| Improvements | Custom ESM loader hooks run in a separate thread |
| Improvements | DuplexPair utility added |
| Security | OpenSSL 3.0.7 bundled |
| Deprecated | Several legacy URL helpers soft-deprecated |
HTTP Keep-Alive On by Default -- What This Means for You
All HTTP and HTTPS clients now set keep-alive: true in their default agent. Prior to v19, each request spun up a new TCP connection unless you explicitly configured an agent with keepAlive: true.
This noticeably improves throughput for microservices that make many rapid HTTP calls to the same upstream. In practice, you'll see lower latency and fewer TIME_WAIT sockets in high-frequency call patterns -- no code changes required.
Built-in Watch Mode
Run Node.js with --watch and the process restarts automatically when the entry file or any of its dependencies change on disk. No nodemon required for development loops.
node --watch server.js
# or watch a specific file
node --watch-path=./src server.js
The implementation uses fs.watch internally. It's experimental in v19, but functional enough for most dev workflows. Production use is not recommended -- use a process manager there instead.
ESM Loader Hooks in a Separate Thread
Custom ESM loader hooks (--loader or --experimental-loader) now run off the main thread. This prevents hook code from blocking the main event loop and resolves a class of deadlock issues when hooks perform async operations during module loading.
This is a breaking behavior change for loaders that rely on shared mutable state between the hook thread and the main thread. Most well-behaved loaders are unaffected.
Intl.NumberFormat v3 via V8 10.7
The new Intl.NumberFormat v3 adds formatRange() and formatRangeToParts(), trailing zero display options, and rounding modes conforming to the ECMA-402 spec update.
const fmt = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
console.log(fmt.formatRange(3, 5)); // $3.00 -- $5.00
FAQ
Will enabling keep-alive by default break existing code?
Unlikely, but connections to servers that do not support keep-alive may behave differently. If you see unexpected behavior, set agent: new http.Agent({ keepAlive: false }) to opt out per-client.
Can --watch be used in production?
No. Use --watch for development only. In production, use a process manager like PM2 or systemd that handles restarts, health checks, and logging properly.
Does the ESM loader thread change affect ts-node or esbuild loaders?
Some loaders needed updates. Check the loader's changelog for Node.js 19 compatibility notes. Most major tools (ts-node, tsx) updated quickly after the release.
Is WebCrypto fully stable in Node.js 19?
Yes. The globalThis.crypto and node:crypto WebCrypto APIs are fully stable and no longer require the --experimental-global-webcrypto flag.
What is DuplexPair used for?stream.Duplexpair() creates two connected Duplex streams that pipe to each other. Useful for testing stream-based protocols without a real network connection -- think in-memory socket pairs for unit tests.