$ the-wire · showcase
Node 26.9.0 adds a generic MAC API, undici walks back its decompression size cap
By RepoJournal · Filed · About Node.js · Composed from the cited sources · methodology
The day's biggest changes are a Node Current release that broadens the crypto surface and an undici fix that replaces a response-size policy with correct stream backpressure handling.
2026-09-16, Version 26.9.0 (Current), @aduh95 nodejs/node
Node 26.9.0 ships two semver-minor crypto additions from Filip Skokan: a generic MAC API and cipher discovery from OpenSSL providers. Both widen what the standard crypto module can do without a native addon, so code that hand-rolled MAC selection or pinned provider-backed ciphers has a supported path now.
fix: honor backpressure in decompression interceptor nodejs/undici
Matteo Collina reworked the earlier decompression fix after deciding a 64 MiB decoded-response cap was the wrong answer to a backpressure bug. The interceptor now stops pulling decoded output when the consumer pauses and propagates writable pressure from the decoder back to the transport, and the size limit is disabled by default. If you applied or worked around the 64 MiB limit, that behavior ...
tls: propagate singleUse to the secure context nodejs/node
tls.connect() set options.singleUse = true, and both TLSWrap.prototype.close() and TLSSocket.prototype._destroySSL() check ssl._secureContext.singleUse before calling context.close() to release the SSL_CTX. Nothing ever assigned the flag to the context, so the check never fired: sockets kept holding their SSL_CTX, and the property read back as undefined.
vfs: write RealFSProvider files to open fd nodejs/node
Under --experimental-vfs, RealFileHandle.writeFile() and writeFileSync() reopened the original path instead of writing through the handle's descriptor. A read-only handle opened with 'r' could overwrite the file, and a write after the backing file was renamed could recreate the old path.
http: don't destroy socket after request completes nodejs/node
Aborting a ClientRequest after the response fully arrived still called socket.destroy(err), but the resulting 'error' fired on a later tick, after responseKeepAlive() had removed socketErrorListener and returned the socket to the agent's free pool. The unhandled error crashed the process; that destroy is now skipped when there is nothing left to cancel. Also landing: fs.openAsBlobSync(), the sy...