Software 45118 Published by

Node.js 26.13.0 'Lithium' entered Long Term Support today, adding no new code beyond v26.12.1 but locking in maintenance through the end of April 2029. The line carries the big 26.x features into LTS: the Temporal API enabled by default, a V8 14.6 upgrade, and Undici 8 as the HTTP layer. It also inherits an aggressive October security patch set of ten CVEs, headlined by a Brotli decoder RCE fixed just before Imperva's red team published a "Node2Shell" exploit. Notably, 26 is the last major under Node's old six-monthly schedule, with v27 switching to an annual release model.



Node.js 26.13.0 'Lithium' reaches LTS and closes out the six-monthly era

Months after shipping the big features, Node.js's 26.x line is now a supported, patched, long-term target. Don't expect 26.13.0 itself to add anything, though.

On October 28, 2026, the Node.js project published version 26.13.0 under the codename 'Lithium', officially moving the 26.x line into Long Term Support. It's a support milestone, not a feature one. The release notes, written by Release manager Richard Lau, are terse by design: "Other than updating metadata, such as the process.release object, no further changes from Node.js 26.12.1 are included."

Nodejs

It would be easy to file this under "routine" and move on. Context changes the picture, though. Node.js 26 debuted in May 2026, when v26.0.0 landed on the 5th under Rafael Gonzaga as one of the more feature-heavy releases in recent memory. It shipped the Temporal API on by default, a fresh V8 engine, and a new Undici HTTP layer. Reaching LTS is the moment that experimental energy gets locked behind a wall of bug fixes and, as it happens, a genuinely aggressive security patch set.

There's a historical wrinkle too. 26.x is the last major release under the project's traditional six-monthly schedule. Node.js 27 and onward will follow an annual-release model. So this promotion doubles as the closing chapter of an era.

Think of the transition in three parts. First, 26.x is now "Active LTS." It steps out of the bleeding-edge "Current" track into a supported one, so it keeps getting bug fixes and, more importantly, security patches for years. Second, there's a hard sunset date: Node 26 'Lithium' is guaranteed updates through the end of April 2029. That's a known end date, which teams quietly appreciate because it lets them plan instead of guessing. Third, LTS inherits v26.12.1 wholesale. With no code changes, whatever shipped in the release right before it is exactly what you get on day one.

The binary ships wherever Node.js normally runs: Windows x64 and ARM64, macOS on Apple Silicon and Intel, a broad Linux spread (x64, ARM64, ppc64le, s390x, plus musl builds), and AIX on ppc64. Source tarballs and PGP-signed SHASUMS are there for anyone who wants to verify. Head here to check your running version:

node -v

A read of 26.13.0 or higher means you're already on the patched, now-LTS line. Keep in mind that a running process keeps whatever decoder is in memory until it exits, so restart after you check.

The features that got Node 26 here

Three features define the line, and they're why 26 is worth an LTS commitment. The single biggest is that the Temporal API now ships enabled by default, with no experimental flag. Temporal is the standards-track date-and-time API meant to finally replace the long-maligned Date object, which has suffered from mutable state, ambiguous local-vs-UTC handling, and error-prone arithmetic for two decades. It offers immutable objects, explicit instant, date, and timezone distinctions, and predictable arithmetic. Contributed by Richard Lau (nodejs/node#61806), it's classified as SEMVER-MAJOR simply because enabling a global by default is technically a breaking change for anyone who has been relying on its absence.

The V8 engine jumped to version 14.6 (14.6.202.33, part of Chromium 146), and with it landed two language proposals: upsert via [Weak]Map.prototype.getOrInsert() and iterator sequencing through Iterator.concat(). The bump also pushes NODE_MODULE_VERSION to 147, which carries a real consequence for native-add-on developers. Prebuilt binaries compiled against earlier Node.js versions now need rebuilding.

Then there's Undici 8 as the HTTP layer. Undici powers fetch() and much of Node's outbound HTTP, so this upgrade shifts real-world behavior. You get closer alignment with the WHATWG Fetch spec and tighter streaming and connection handling. For high-throughput workloads that means more predictable cross-environment behavior. But it's also a reason to test, since low-level fetch semantics can shift in subtle ways.

Cleaning up alongside the additions, Node 26 also removed a pile of legacy surface area. The long-dreaded http.Server.prototype.writeHeader() is fully gone in favor of writeHead(). The legacy _stream_* modules are gone too, joined by a batch of crypto and module.register() deprecations. None of this breaks code immediately, but the warnings are a signal, and auditing usage now is far cheaper than an emergency migration later.

Why this LTS lands during a tense week

The timing isn't random. A week before 26.13.0 shipped, Node.js rolled out v26.12.1 on October 21, 2026, and it was one of its most substantial security releases in years. Because 26.13.0 sits directly on top of it, LTS users inherit the whole hardening set for free.

The October cycle patched ten CVEs across the supported lines (22.x, 24.x, and 26.x). Four are High, and one is the real headline.

CVE-2026-111497 is a High-severity out-of-bounds write in the bundled Brotli decoder that permits remote code execution. It's worth dwelling on because Brotli decompression happens automatically. fetch() transparently decodes Content-Encoding: br responses with no opt-out, and Express 5 body parsers inflate Brotli request bodies by default. Nothing manual is required to trip it.

The fix is a cherry-pick of an upstream Brotli commit titled "Detect and report invalid stream earlier." Imperva's red team reportedly published a working exploit dubbed "Node2Shell" against a stock Node image, fired through both fetch() and Express 5. As of late October, no live exploitation had been confirmed, which is the good news.

The other three High CVEs cluster around TLS and DNS. One lets a loosely resolving host bypass TLS hostname checks, another repeats the trick using fullwidth-digit IP addresses, and a third truncates dns.resolve() names containing a NUL byte. Three more sit in the Medium range, touching keep-alive sockets, non-canonical IPv4 hostnames, and an entropy cache leak that can bleed into startup snapshots. The last two are Low, covering ZipFile header validation and a filesystem realpath permission bypass.

On top of the CVEs, the cycle refreshed several bundled dependencies: c-ares to 1.34.9, Undici to 8.12.2, and the CA root store to NSS 3.131.1, which adds a compiled-in blocklist for compromised eMudhra certificate intermediates.

The takeaway is blunt. Anyone still on a supported line older than these patches, especially on the EOL 20.x, 18.x, and earlier, was exposed. The supported lines are now patched, but you have to restart to actually gain the fix. And that's a detail ops teams forget at their peril.

There's also a build change worth flagging before you deploy. Since Node.js 25, official Linux binaries are linked against libatomic, which some distributions don't ship by default. I've watched the libatomic footgun take out a handful of production deploys over the last year, nothing dramatic, just processes that refuse to start with an ugly undefined-symbol error and no helpful stack trace. If you're moving to v26.x, make sure libatomic is present on the target systems or you may watch processes die at startup. Other 26.x build shifts include a GCC bump to 13.2, dropped Python 3.9 support, and fresh Rust toolchain needs tied to the Temporal default work.

To understand why developers are watching v26's LTS transition, it helps to situate it against the project's shifting philosophy. Node.js traditionally ran an "even = LTS, odd = Current" rhythm with roughly two major releases per year. Then the project formally announced it was evolving the schedule. Starting with Node.js 27, there will be one major release per year, version numbers will track the calendar year (27 roughly means 2027), and every major goes straight to LTS. That makes 26 the last major under the old cadence, which is a fair way to spend a goodbye: pack in the features, lock in the security, and hand off something stable.

For most production workloads, v26 'Lithium' is now a safe bet. It carries the crown jewels, Temporal by default, a modern V8, a new HTTP layer, plus three years of guaranteed support, and stands as the final stable reference point before the annual model reshapes everything. Though it's arguably a larger commitment to inherit at the end of an era, that's just what LTS means: you're locking in a version and trusting it to outlive its own release schedule.

If you're on v26.x, confirm you're at or above 26.13.0 and you're already on a patched line. You can verify the Brotli fix with a one-liner:

node -p "'BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH' in require('zlib').constants"

A true answer means the patched decoder is in place. You'll also want to inventory every Node binary on your systems, since version managers, distro packages, container base images, and single executable applications can each point at different versions:

ps -eo pid,lstart,args | grep -E '[n]ode( |$)'

After patching, restart. A live process keeps the old decoder and stale entropy caches until it exits, and containers need a rebuild from a fresh image regardless. And if you're still on an EOL line like 20.x or older, you get no upstream fixes at all, that's not a feature request waiting to be granted, it's a dead end. Plan a migration to 26.x, or move to an extended-support provider until you can.

Head here to download the release.