Node.js 24.18.0 'Krypton' LTS Lands Buffer.poolSize at 64 KiB, Web Crypto's TurboSHAKE and KangarooTwelve, and http.writeInformation for Arbitrary 1xx Codes

Node.js 24.18.0 'Krypton' LTS Lands Buffer.poolSize at 64 KiB, Web Crypto's TurboSHAKE and KangarooTwelve, and http.writeInformation for Arbitrary 1xx Codes

lschvn

Node.js 24.18.0 'Krypton' (LTS), published 2026-06-23 23:11 UTC by @richardlau and prepared by @sxa, is the largest release on the v24 LTS line since the line went Active in October 2025. It lands eight SEMVER-MINOR changes: the Buffer.poolSize 64 KiB default backported from Current, RFC 9861's TurboSHAKE and KangarooTwelve added to Web Cryptography, http.writeInformation for arbitrary 1xx status codes, V8 precise coverage exposed to the JS runtime, and JWK import-export for the ML-KEM and SLH-DSA post-quantum key families. The same day, Node.js 22.23.1 'Jod' (LTS) ships a two-commit follow-up to the 06-18 v22.23.0 security release, backing out an http agent change that triggered an unexpected re-stream behavior in real production HTTP clients.

The release lands on the LTS line the same week that the Node.js June 2026 security releases shipped, and the timing is intentional: the security release closed 14 CVEs across v18, v20, v22, and v24 on 2026-06-18 (covered in the previous Node.js security release piece), and v24.18.0 is the next feature release on the v24 line that production users can take in one step. The follow-up hotfix in v22.23.1 is the second half of the same week, since the v22.23.0 fix produced unexpected stream behavior in real workloads and the team chose to revert in v22.23.1 rather than wait for v22.24.0.

Buffer.poolSize default doubles to 64 KiB

The most impactful runtime change is the default Buffer.poolSize increase from 8 KiB to 64 KiB, contributed by Matteo Collina (#63597, 7 additions, 2 files). The slab allocator's pool check is size < (Buffer.poolSize >>> 1), so with the 8 KiB default the threshold is 4 KiB and the strict inequality means a 4 KiB allocation itself bypasses the pool. The current default helps allocations from 1 byte to 3999 bytes and abruptly stops at the page-aligned, HTTP-frame-sized boundary where many real allocations land.

The PR description cites three reasons for the change. The 4 KiB cliff is the first. The second is that the default has been 8 KiB since May 2015, predating HTTP/2's 16 KiB to 1 MiB frame sizes, modern stream chunk sizes, and the ~10x growth in typical RAM. The third is that many Buffer.allocUnsafe calls in core (fs.readFileSync for non-utf8 reads, the HTTP parser, the stream chunkers) sit in the 4 KiB to 64 KiB range and miss the pool.

The PR's benchmark, run on 8 worker threads in a single process on Linux 6.8 with glibc 2.39 on an i7-7700, shows:

File size8 KiB pool (default)64 KiB poolΔ
512 B404k ops/s431k ops/s+7%
2 KiB360k ops/s367k ops/s~
4 KiB326k ops/s360k ops/s+10%
8 KiB202k ops/s254k ops/s+26%
16 KiB148k ops/s181k ops/s+23%
64 KiB86k ops/s87k ops/s~
1 MiB8.7k ops/s8.6k ops/s~

The new 64 KiB default extends pool coverage to allocations up to ~32 KiB. The change is the first time the default has moved since 2015. It is not breaking, it only affects the default, and applications can still set Buffer.poolSize manually. The same change already shipped on the Current line in Node.js 26.3.0 on 2026-06-01; v24.18.0 is the first time it lands on the LTS line. The headline of that earlier article is now also the headline of this one for v24 users.

Web Cryptography gains TurboSHAKE and KangarooTwelve

The second headline is the addition of TurboSHAKE and KangarooTwelve (PR #62183, 1,521 additions, 13 files, Filip Skokan) to the Web Cryptography API. Both are extendable-output hash functions from the same Keccak permutation family as SHA-3 and SHAKE, standardized in RFC 9861. They are faster than SHAKE on long messages and short fixed-length digests; KangarooTwelve is the IETF's recommended tree-hash mode for high-throughput applications, and the browser ecosystem is following the same draft through the WICG webcrypto-modern-algos proposal.

The Node.js implementation ports OpenSSL's keccak1600 primitives directly. The work is gated behind the unstable algorithm flag until OpenSSL ships native support for both primitives; at that point, the algorithms will move to stable node:crypto and the Web Crypto gate will be lifted. The PR is one of the first times Node.js has shipped a Web Crypto algorithm before the OpenSSL release that backs it, and the upstream openssl/openssl#30304 is the tracker that will gate the stabilization.

The release also lands a multi-PR hardening of the Web Cryptography stack. PR #63363 (Filip Skokan) hardens WebCrypto against prototype pollution, refactors the async path to a new internal CryptoJob mode, passes CryptoKey handles directly into the KDF jobs, and removes the async keyword from the Web Crypto methods where the work is actually synchronous underneath. PR #63255 (Filip Skokan) wires the BoringSSL build path so that ML-DSA, ML-KEM, ChaCha20-Poly1305, and AES-KW are available in Web Cryptography when Node.js is built against BoringSSL. PR #63111 tightens the CryptoKey algorithm slots and KeyObject internal slots so that the two types cannot accidentally share state.

Post-quantum JWK support for ML-KEM and SLH-DSA

PR #62706 (842 additions, 39 files, Filip Skokan) adds JSON Web Key import and export for the ML-KEM (formerly Kyber) and SLH-DSA (formerly Sphincs+) post-quantum key families, both selected by NIST in FIPS 203 and FIPS 205. The JWK shapes follow the IETF LAMPS WG drafts and the JOSE registrations.

Combined with the BoringSSL-side ML-KEM and ML-DSA wiring in PR #63255, the Web Cryptography side of Node.js now matches the post-quantum work that the Current line has been carrying since the 26.x cycle began. A single Node.js binary can now serve RSA, ECDSA, Ed25519, ML-KEM, ML-DSA, and SLH-DSA JWKs in the same Web Crypto namespace, which matters for the production rollout of post-quantum TLS: the same crypto.subtle namespace that a server uses to verify an RSA signature can now verify an ML-DSA signature, and the same importKey / exportKey path that handles a P-256 JWK can now handle an ML-KEM-768 JWK.

PR #62905 adds a separate guard against duplicate ML-KEM JWK key_ops, which is the kind of edge case that surfaces in interop tests with the browser implementations. PR #62626 is a smaller fix that guards against a size_t overflow on the experimental 32-bit architecture; the change is in the same family as the 64-bit-architecture fixes that landed in v24.15.0.

http.writeInformation for arbitrary 1xx status codes

PR #63155 (306 additions, 7 files, Tim Perry) adds response.writeInformation({ status, headers }), a generic HTTP/1 API for sending arbitrary 1xx status codes. The runtime previously exposed res.writeContinue for 100 and res.writeEarlyHints for 103 and that was it; anyone who needed a custom 1xx or who was writing a proxy that needed to forward a 1xx from the upstream had to use the private res._writeRaw method, which the PR description calls out as something the Node.js test suite itself had been doing.

The new method mirrors the existing HTTP/2 additionalHeaders shape and supports any 1xx status code except 101, which switches protocols and is still handled by the upgrade event. The existing writeContinue and writeEarlyHints are refactored on top of the new method. There is one inconsistency the PR keeps as-is: the H1 path throws if a final status has already been sent, while the H2 path no-ops. The PR description flags this as a candidate for alignment in a future major bump.

The fix closes three long-standing issues, #22624, #27921, and #7588, which had been closed as stale over the years because no general API existed. Proxy authors get a single API that works for the IETF-defined codes, custom 1xx values, and any future standardized 1xx without a per-status method.

V8 precise coverage exposed to the JS runtime

The inspector precise coverage work (commit 8c989ec4a3, sangwook, SEMVER-MINOR) is the smallest headline in the release by line count and the most useful one for anyone running coverage on the v24 LTS line. The change exposes V8's precise coverage start signal to the JS runtime through a new internal binding, so node:inspector and the test runner can both start precise coverage at runtime rather than only at bootstrap via NODE_V8_COVERAGE or --experimental-test-coverage.

The companion PR #63079 (sangwook) wires the same primitive into the test runner's run() API: run({ coverage: true, isolation: 'none' }) now correctly collects coverage, and the test-file exclusion default is applied consistently between the CLI and the API path. The PR fixes a real bug in test_runner where the API path was reporting an empty file list because the V8 coverage flag was only set at bootstrap.

The change is the same precise coverage work that has been shipping incrementally in 24.16.0 and 24.17.0; the 24.18.0 piece is the final exposure that lets application code start coverage on demand. For users running c8 or nyc against the v24 line, this means the test runner's coverage path is now first-class on LTS.

The stream revert and the v22.23.1 follow-up

The release reverts one change from 24.16.0: PR #63834 (Stewart X Addison) backs out the 'stream: noop pause/resume on destroyed streams' change that landed on 2026-05-21. The intent was to make stream cleanup more idempotent, but real-world HTTP and process-spawn pipelines relied on pause() being a no-op-then-clean even after destroy, and the change produced 'Cannot call method on destroyed stream' failures in code paths that were correct before the change.

The same day, Node.js 22.23.1 (16:44 UTC, @RafaelGSS) ships a related follow-up: PR #64004 (Matteo Collina) backs out the v22.23.0 security release's change to the http agent, which had been adding a stream listener to idle agent sockets and producing an unexpected re-stream behavior in production HTTP clients. v22.23.0 users should upgrade to 22.23.1; the fix lands in v24.18.0 at the same time, so v24.17.0 users should upgrade to 24.18.0 to pick up both the stream revert and the agent revert.

The two reverts are unrelated at the API level but land together because they were both caught in production in the same week. The Node.js 22 release schedule has 22.x in Maintenance LTS through October 2026, and the team's choice to issue a 22.23.1 one-week hotfix rather than wait for 22.24.0 reflects how the LTS branches are now used as production targets for long-running services.

What 24.18.0 does not change

The release does not change the v8 major version, the libuv major version, or the public addon API. The Node-API surface picks up PR #62710 (Yilong Li), which adds SharedArrayBuffer support to napi_create_typedarray, a small but real fix for native modules that want to expose SharedArrayBuffer views to JS. The fs.Stats Date properties become enumerable (PR #63328, Livia Medeiros), a long-standing fix that finally matches the spec. SQLite is updated to 3.53.1 (PR #63217), simdjson to 4.6.4 (PR #62811), and npm to 11.16.0 (PR #63602). The release also includes PR #62612, which adds AI assistants' files to the repo's .gitignore; a small meta change that is itself a signal of where the Node.js maintainers think the next generation of contributor tooling is going.

The full Node.js 24 LTS release schedule projects Active LTS maintenance through October 2027 and Maintenance LTS through October 2028. v24.18.0 is the second release of June on the v24 line and the first to ship the Buffer pool and post-quantum JWK work that has been accumulating on Current for two months.

Frequently Asked Questions

Vite 8.1.0 Stable Adds Bundled Dev Mode (15x Startup on 10k React Components), Ships WASM ESM Imports and Chunk Import Map, Extends server.fs.deny With .npmrc and Private Keys

Vite 8.1.0 stable, published 2026-06-23 by the Vite Team (announcing-vite8-1), graduates Bundled Dev Mode from an experimental flag into a documented --experimental-bundle entry point (15x faster cold start on a 10k React-component app, 10x faster full reloads, 3x faster cold-start rendering and 40% faster full reloads reported by Linear), stabilises the WASM ESM Integration direct .wasm imports and build.chunkImportMap that shipped in 8.1-beta on 2026-06-15, brings Lightning CSS one step closer to default by adding external-CSS-in-CSS and plugin file dependencies, bumps Rolldown to 1.1.2 (1.1.3 follows the same day), pins rolldown with a tilde range so patch releases flow through without a Vite PR, extends server.fs.deny with .npmrc, .yarnrc.yml, and *.{key,p12,pfx,cer,der}, and emits a runtime warning when envFile: false is used (the deprecation is already documented in the types).

Node.js 26.4.0 'Current' Ships node:vfs Subsystem (Matteo Collina), ESM Loader Package Maps (Maël Nison), TLS Certificate Compression, TCP_KEEPINTVL/TCP_KEEPCNT, and argon2 Stable

Node.js 26.4.0 (Current), published 2026-06-24 by @aduh95, lands eight SEMVER-MINOR changes: a minimal node:vfs subsystem that mounts user-supplied virtual filesystems (PR #63115, Matteo Collina) plus a follow-up that dispatches node:fs/promises to mounted VFS instances (PR #63537), package maps for ESM loaders that route bare specifiers through the loader hooks (PR #62239, Maël Nison), TLS certificateCompression that wires RFC 8879 zlib and zstd compression through the OpenSSL build config (PR #62217, Tim Perry), TCP_KEEPINTVL and TCP_KEEPCNT support in net.Socket.setKeepAlive (PR #63825, Guy Bedford), caller-supplied buffers in fs.readFile / fs.readFileSync (PR #63634, Matteo Collina), closeIdleConnections that now also drops pre-request sockets (PR #63470, semimikoh), net.BlockList advanced to Release Candidate stability (PR #63050), and crypto argon2 + KEM encap/decap marked stable (PR #63924, Filip Skokan). The release also adds WebCrypto cSHAKE (PR #63988), QUIC listEndpoints (PR #63536) and X509Certificate handles (PR #63191), dgram connectSync / bindSync (PRs #63838 + #63932, Guy Bedford), early-TCP net.BoundSocket (PR #63951), an experimental fast FFI call path for AArch64 and x86_64 (PRs #63068 + #63941, Paolo Insogna), npm 11.17.0 (PR #63857), sqlite 3.53.2, and libffi 3.6.0.

Related articles

More coverage with overlapping topics and tags.

Deno 2.9 Ships 1.98x Faster Cold Start, 2.2-3.1x Less RSS Under Load, Default-On npm Minimum Release Age, No-Downgrade Trust Policy, and Built-In Snapshot Testing
runtimes

Deno 2.9 Ships 1.98x Faster Cold Start, 2.2-3.1x Less RSS Under Load, Default-On npm Minimum Release Age, No-Downgrade Trust Policy, and Built-In Snapshot Testing

Deno 2.9 (Bartek Iwańczuk, published 2026-06-25 on deno.com/blog/v2.9) is the largest Deno release of the cycle. Cold start drops from 34.2 ms to 17.3 ms (1.98x), peak RSS on the Deno.serve realworld workload drops 2.2x (142 MB → 64 MB) and 3.1x on 1 MiB bodies (197 MB → 63 MB), and Deno.serve throughput climbs 1.27x realworld (56.8k → 72.4k req/s), 1.11x plaintext, and 1.18x on 1 MiB bodies. Supply chain hardening: npm minimum-release-age is enabled by default with a 24h window (PR #35458), and a new opt-in no-downgrade trust policy (PR #34927) refuses to resolve any version whose trust evidence (staged publish, trusted publishing, provenance attestation) is weaker than the strongest evidence on any earlier-published version of the same package. Test runner parity: built-in t.assertSnapshot() (#35139), Deno.test.each (#34938), --shard for CI fan-out (#35057), retry and repeats (#35053), change-aware --changed and --related (#35199), and coverage thresholds (#35056). Lockfile interop: deno install seeds deno.lock from package-lock.json, pnpm-lock.yaml, yarn.lock, or bun.lock (#34296, #35330, #35346, #35350, #35394), pnpm-workspace.yaml auto-migrates to deno.json / package.json (#34993), and git merge conflict markers in deno.lock auto-resolve (#34726). Plus: deno desktop graduates from experimental (the June 16 PR #33441), deno link / deno unlink / deno list / deno watch subcommands, stable --unsafe-proto (#34738), Web Locks API (#31166), Happy Eyeballs v2 (RFC 8305) (#31726), navigator.userAgentData (#34743), the WebCrypto Modern Algorithms proposal (ML-KEM, ML-DSA, SLH-DSA, ChaCha20-Poly1305, SHA-3 family, KMAC, Argon2) (#34447, #34448, #34914, #35223), Node 26.3.0 compat (#34746, #34747), Node-API v10 (#35270), and CSS module imports under --unstable-raw-imports (#35093). 165+ PRs land in this cycle.
Fastify v5.9.0 Adds `request.mediaType` and `onMaxParamLength`, Hardens `forwarded` Header Trust, Chunks Large HTTP/2 Replies, and Moves Type Tests to TSTyche
security

Fastify v5.9.0 Adds `request.mediaType` and `onMaxParamLength`, Hardens `forwarded` Header Trust, Chunks Large HTTP/2 Replies, and Moves Type Tests to TSTyche

Fastify v5.9.0, published on 2026-06-28 (github.com/fastify/fastify), is the first minor release of the v5 line in 2026 and a substantial 65-PR cycle. The headline features are `request.mediaType` (a typed accessor for the negotiated media type, [#6653](https://github.com/fastify/fastify/pull/6653) by climba03003), `onMaxParamLength` route option ([#6716](https://github.com/fastify/fastify/pull/6716) by climba03003), and a security fix that no longer trusts `X-Forwarded-Host` and `X-Forwarded-Proto` when the incoming socket is missing ([#6684](https://github.com/fastify/fastify/pull/6684) by mcollina). The cycle ships an HTTP/2 buffer-chunking fix for large replies ([#6746](https://github.com/fastify/fastify/pull/6746) by mcollina), three schema-related performance wins (deferred `getSchemaSerializer` content-type parsing #6692, cached `ContentType` objects in `ContentTypeParser` #6694, `typeof` guard before `toString.call` in `send` / `onSendEnd` #6693 by aquie00t), Node.js 26 added to the test matrix ([#6728](https://github.com/fastify/fastify/pull/6728) by Fdawgs) and Node.js 20 dropped from the yarn CI matrix ([#6662](https://github.com/fastify/fastify/pull/6662) by Tony133), the migration of the type-test suite from hand-rolled `expect-type` to [TSTyche](https://github.com/mrazauskas/tstyche) ([#6532](https://github.com/fastify/fastify/pull/6532) by mrazauskas, with follow-ups #6726 and #6727), and a TypeScript-only fastify-plugin v6.0.0 bump. Other notable fixes: trailer `res.end` deduplication (#6676), trailer duplicate-completion guard (#6714), `error.code` on routing errors (#6678), `hasRequestDecorator` / `hasReplyDecorator` catching constructor-assigned built-ins (#6753), `getValidationFunction()` allowed to return `undefined` (#6665), and a socket `_meta` clear that closes a keep-alive leak (#6799).
Node.js 26.4.0 'Current' Ships node:vfs Subsystem (Matteo Collina), ESM Loader Package Maps (Maël Nison), TLS Certificate Compression, TCP_KEEPINTVL/TCP_KEEPCNT, and argon2 Stable
security

Node.js 26.4.0 'Current' Ships node:vfs Subsystem (Matteo Collina), ESM Loader Package Maps (Maël Nison), TLS Certificate Compression, TCP_KEEPINTVL/TCP_KEEPCNT, and argon2 Stable

Node.js 26.4.0 (Current), published 2026-06-24 by @aduh95, lands eight SEMVER-MINOR changes: a minimal node:vfs subsystem that mounts user-supplied virtual filesystems (PR #63115, Matteo Collina) plus a follow-up that dispatches node:fs/promises to mounted VFS instances (PR #63537), package maps for ESM loaders that route bare specifiers through the loader hooks (PR #62239, Maël Nison), TLS certificateCompression that wires RFC 8879 zlib and zstd compression through the OpenSSL build config (PR #62217, Tim Perry), TCP_KEEPINTVL and TCP_KEEPCNT support in net.Socket.setKeepAlive (PR #63825, Guy Bedford), caller-supplied buffers in fs.readFile / fs.readFileSync (PR #63634, Matteo Collina), closeIdleConnections that now also drops pre-request sockets (PR #63470, semimikoh), net.BlockList advanced to Release Candidate stability (PR #63050), and crypto argon2 + KEM encap/decap marked stable (PR #63924, Filip Skokan). The release also adds WebCrypto cSHAKE (PR #63988), QUIC listEndpoints (PR #63536) and X509Certificate handles (PR #63191), dgram connectSync / bindSync (PRs #63838 + #63932, Guy Bedford), early-TCP net.BoundSocket (PR #63951), an experimental fast FFI call path for AArch64 and x86_64 (PRs #63068 + #63941, Paolo Insogna), npm 11.17.0 (PR #63857), sqlite 3.53.2, and libffi 3.6.0.

Comments

Log in Log in to join the conversation.

No comments yet. Be the first to share your thoughts.