Node.js 26.4.0 'Current', published 2026-06-24 23:38 UTC by @aduh95 with @aduh95, @targos, and @jasnell as release stewards, is the second Current release of June on the v26 line and the largest of the cycle since 26.3.0 on 2026-06-01. It lands eight SEMVER-MINOR changes: a minimal node:vfs subsystem (Matteo Collina) plus a follow-up that dispatches node:fs/promises to mounted VFS instances (PR #63537), package maps for ESM loader hooks (Maël Nison, the Yarn creator), TLS certificateCompression on top of the OpenSSL compression work (Tim Perry), TCP_KEEPINTVL and TCP_KEEPCNT in net.Socket.setKeepAlive (Guy Bedford), caller-supplied buffers in fs.readFile (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 plus crypto.encap / crypto.decap marked stable (PR #63924, Filip Skokan).
The release lands two days after Node.js 24.18.0 'Krypton' (LTS) on 2026-06-23, and the timing is the usual pattern: the Current line carries the experimental work that eventually backports to LTS. The Buffer.poolSize 64 KiB default is the canonical example, having shipped on Current in 26.3.0 on 2026-06-01 and on LTS in 24.18.0 two days ago. The VFS subsystem, the package maps for ESM loaders, and the TLS certificate compression are the same kind of work: significant enough that they earn their own Current release, but still experimental enough that they will not reach the v24 LTS line for at least one more cycle.
node:vfs, a new core subsystem
The most architecturally significant change in 26.4.0 is the new node:vfs subsystem. PR #63115 (Matteo Collina) adds a minimal in-process VFS layer that application code can mount and unmount at runtime. The subsystem exposes four functions: mount(prefix, vfsInstance), unmount(prefix), getMount(prefix), and getMounts(). The vfsInstance is a JavaScript object that implements a small async interface (readFile, stat, readdir, plus a handful of others), and Node.js dispatches node:fs/promises calls whose path starts with the mounted prefix to the instance instead of the OS filesystem.
The follow-up PR #63537 (Matteo Collina) wires the layer into node:fs/promises directly. A readFile('/vfs/project/src/index.ts') call on a prefix that has been mounted with an in-memory VFS instance that contains the project tree returns the in-memory contents without touching disk. The integration is the runtime-side foundation for sandboxed execution: build tools can hand a loader a virtual filesystem that contains the project tree, serverless platforms can hand a request handler a virtual filesystem that contains only the request scope, IDE language servers can hand a debugger probe a virtual filesystem that contains the file being debugged. Production users on the v24 LTS line will not see this for at least one release cycle, but the Current line now has the primitive that the next round of tooling work will sit on.
The VFS instance interface is intentionally minimal in this first cut. The PR description is explicit that symlinks, file watching, and real-path resolution are out of scope and will land in follow-up Current releases. The companion documentation PR describes the surface as "the smallest viable VFS that lets us replace ad-hoc fs monkey-patching in tooling" and notes that the API will go through at least one Current cycle before it is a candidate for stabilization.
Package maps for ESM loader hooks
The second architectural change is PR #62239 (Maël Nison), which implements package maps for ESM loader hooks. The runtime already has a package.json-style imports map that lets the application graph resolve bare specifiers (#internal/api, lodash/sortBy, react/jsx-runtime); loader hooks previously had to re-implement the map lookup themselves because the resolution was internal to the module loader. The new API exposes the same resolution as a first-class call on the loader hooks, so a loader that needs to know whether a specifier resolves to a remapped path (or to a subpath) can read the result directly without walking the package.json itself.
For build tool authors, this is the missing piece for implementing Node.js-compatible import maps on top of a bundler. The import-map spec already defines the wire format, and the browser implementations have shipped import maps for years. Node.js has had the underlying imports field for the same period, but the loader hooks API never exposed the resolution path that the host runtime used; loader authors had to walk the package.json and re-implement the map. Maël Nison, who authored the Yarn package manager and was the primary contributor to the Yarn resolutions mechanism, is the right author for this work, and the PR is the first time the ESM loader hooks expose the package map machinery as a first-class API.
The PR description frames it as the loader hooks side of the same import-map work that Vite 8.1's build.chunkImportMap ships at the build-output layer (covered in our Vite 8.1 stable piece). Vite 8.1's chunkImportMap is a bundler-side feature that emits a browser import map for chunk URL resolution; 26.4.0's loader package maps are the host-runtime side that a bundler would consume when running in Node.js. The two pieces are independently useful, but they sit at different layers of the same stack.
TLS certificate compression
The third SEMVER-MINOR change is PR #62217 (Tim Perry), which adds a certificateCompression option to tls.createSecureContext and https.Server. The option takes an array of compression algorithms ('zlib' and 'zstd'), and the PR wires the RFC 8879 extension through the OpenSSL build config so the compression primitives are linked into the Node.js binary. The companion commit e44b5d487e updates the OpenSSL build config to support compression; without that, the OpenSSL-side support would not be available to the Node.js TLS layer.
TLS certificate compression is most useful when the chain includes a large post-quantum signature, which is the same reason Chrome and Firefox have been rolling it out over the past year. Servers that enable it on a chain that includes an ML-DSA-65 or ML-DSA-87 signature (the NIST FIPS 204 primary signatures) should see a noticeably shorter TLS handshake. The PR is also the first time the OpenSSL build path exposes the same TLS surface that the BoringSSL path already supports, which means a single Node.js binary can serve the same certificateCompression option regardless of which TLS backend it was built against.
TCP_KEEPINTVL and TCP_KEEPCNT in setKeepAlive
The fourth SEMVER-MINOR change is PR #63825 (Guy Bedford), which adds TCP_KEEPINTVL and TCP_KEEPCNT to the options accepted by net.Socket.setKeepAlive(enable, initialDelay). Before 26.4.0, setKeepAlive only accepted the initial-delay argument, and the interval between probes and the number of probes before the connection was declared dead were OS defaults. On Linux the defaults are 75 seconds between probes and 9 probes before drop, which means a half-open connection survives for ~11 minutes; on macOS the defaults are similar. Library authors (database drivers, message brokers, edge runtimes, QUIC clients) could not tune these without dropping to a native module.
With the new options, the application code can shorten the probe interval to seconds and the count to a small number, which is the configuration the production database drivers have wanted for years. The companion PR #63951 (Guy Bedford) adds net.BoundSocket, a synchronous early-TCP binding primitive for code paths that need to bind a port before yielding to the event loop. The two pieces are the first substantial net changes on the v26 Current line and are the same family as the TCP keep-alive work that the Node.js 24.18.0 LTS line shipped.
Crypto stabilization, QUIC, dgram, and FFI
The other five SEMVER-MINOR pieces complete the picture. PR #63924 (Filip Skokan) marks crypto.argon2 (Argon2id, Argon2i, Argon2d) and crypto.encap / crypto.decap (key encapsulation for ML-KEM and RSA-OAEP) as stable. Both have been behind an experimental flag since the 22.x cycle, and the stabilization is the prerequisite for libraries to depend on them without the flags. The release also adds WebCrypto cSHAKE support (PR #63988, Filip Skokan), which extends the Web Crypto cSHAKE work that shipped on the v24 line.
net.BlockList advances to Release Candidate stability (PR #63050, alphaleadership), the last step before stable in the next Current release. On the QUIC side, PR #63536 (James M Snell) adds a listEndpoints API and PR #63191 (Tim Perry) changes the certificate accessor to return an X509Certificate handle instead of the raw OpenSSL handle. dgram gets synchronous connectSync and bindSync (PRs #63838 + #63932, Guy Bedford).
The experimental fast FFI work (PR #63068 + PR #63941, Paolo Insogna) lands for AArch64 and x86_64, with the follow-up PR #63794 (Stewart X Addison) porting the same machinery to riscv64. The path is gated behind --experimental-ffi and the API will go through at least one Current cycle before it is a candidate for the LTS line.
Other changes in 26.4.0
The release ships a long tail of smaller changes. PR #63634 (Matteo Collina) adds caller-supplied buffer support to fs.readFile and fs.readFileSync, the first time the file read API lets the caller pass in the destination buffer instead of letting Node.js allocate internally. PR #63470 (semimikoh) makes http.closeIdleConnections close pre-request sockets too, fixing a real bug where idle keep-alive sockets held a connection open after the request that owned them had completed.
npm ships 11.17.0 (PR #63857), sqlite updates to 3.53.2, libffi updates to 3.6.0 (PR #64040), and acorn updates to 8.17.0. The release also marks Node.js 25 as End-of-Life in the documentation and ships a long stream optimization patch (Matteo Collina, James M Snell, Trivikram Kamat) that reduces allocations on the WHATWG streams hot paths, fixes the Utf8Stream stall after a full write of multi-byte data, and refines the stream/iter backpressure. The companion PR #62986 fixes Writable.toWeb() desiredSize for non-object-mode streams, a long-standing bug that surfaced whenever the WHATWG streams adapter was used with a binary stream.
The full Node.js 26 release schedule projects Current maintenance through October 2026, at which point v26 enters Active LTS. Production users on the v24 LTS line should stay on 24.18.0 (the Node.js 24.18.0 'Krypton' LTS release we covered two days ago) for at least the next quarter; the v24.19.0 follow-up will pick up the experimental work from 26.x Current as it stabilizes.



