Skip to main content
October 30, 20269 min read

Node.js 26 LTS Adds a Modern Date API and Support to 2029

Get technical support

The day-to-day nobody has time for

Node.js 26 became the long-term support release on October 28, with fixes until April 2029. It turns on the Temporal date API by default, and Node.js 24 stays supported until 2028, so the upgrade can be planned calmly. Here is what changes and how to move.

What Changed on October 28

On October 28, 2026, the Node.js project published version 26.13.0 and moved the 26 line into Long Term Support under the codename Lithium. The release carries no new code compared with 26.12.1. What changes is the status, and for anyone running Node.js in production the status is what counts.

LTS is the stage where a release line settles down. Changes are reviewed for stability before they land, and the line receives security patches and bug fixes for the rest of its life, which for Node.js 26 runs until April 30, 2029. The Node.js project itself notes that most users wait for this moment before they upgrade, and the ecosystem moves with them. The official node:lts Docker tag already points to 26, and AWS lists November 2026 as the target month for its Lambda runtime.

The best part is that nobody has to hurry. Node.js 24 keeps getting security fixes until April 30, 2028, so a team on 24 can treat this as routine maintenance and plan it for a quiet week.

Where Each Node.js Line Stands

Release lineStatus todaySecurity fixes until
Node.js 20End of life since April 30, 2026Ended
Node.js 22MaintenanceApril 30, 2027
Node.js 24Maintenance since October 20, 2026April 30, 2028
Node.js 26Active LTS since October 28, 2026April 30, 2029
Node.js 27Alpha, stable release planned for April 2027April 30, 2030 (planned)

Maintenance means a line still gets security fixes and critical bug fixes, while new features stop arriving. Active LTS is the newest line the project considers ready for production.

Read as a plan, the table is simple. A team still on 20 is past end of life, and 26 is now the natural place to land. A team on 22 has six months of fixes left, and going straight to 26 saves one upgrade. A team on 24 is in good shape and has about eighteen months to move whenever it suits.

Dates That Finally Behave

The change most developers will notice in Node.js 26 is Temporal, the new built-in date and time API, now switched on by default. On Node.js 24 it still sits behind an experimental flag.

JavaScript's Date object has caused bugs for decades. It mixes local time with UTC, knows no time zone other than the machine's own, and does arithmetic that surprises people. A classic case is adding one month to January 31.

const d = new Date(2026, 0, 31);
d.setMonth(d.getMonth() + 1);
d.toDateString(); // "Tue Mar 03 2026"

Temporal.PlainDate.from("2026-01-31").add({ months: 1 }).toString();
// "2026-02-28"

Date runs past the end of February and lands in March. Temporal stays in February and stops on its last day, which is what a billing cycle or a subscription renewal expects.

Time zones get the same care. A daily job set for 9:00 in London should still run at 9:00 the morning after the clocks change, and Temporal knows that "one day later" and "24 hours later" are different things.

const run = Temporal.ZonedDateTime.from("2026-03-28T09:00[Europe/London]");

run.add({ days: 1 }).toString();
// "2026-03-29T09:00:00+01:00[Europe/London]"

run.add({ hours: 24 }).toString();
// "2026-03-29T10:00:00+01:00[Europe/London]"

The UK moves to summer time on March 29, 2026, so the two answers differ by an hour. With Date, keeping track of that is left to you or to a library.

Over time this means fewer dependencies. Libraries such as Moment.js, Luxon and date-fns exist largely to fill the gaps Temporal now covers, so new code can use the built-in API directly. Existing code needs no change, since Date is still there and works exactly as before.

Other Improvements in Node.js 26

Node.js 26 ships with V8 14.6, the JavaScript engine from Chromium 146, up from V8 13.6 in Node.js 24. It brings a few small conveniences that tidy up everyday code. Map and WeakMap gain getOrInsert() and getOrInsertComputed(), which replace the familiar pattern of checking for a key before setting it.

const byHost = new Map();
for (const entry of logLines) {
  byHost.getOrInsertComputed(entry.host, () => []).push(entry);
}

Iterator.concat() joins several iterators into one without building arrays first. Undici, the HTTP client behind the built-in fetch, moves to version 8, and 26.13.0 ships with npm 11.20.0.

TypeScript support also keeps maturing. Running .ts files directly through type stripping has been stable since Node.js 24.12, and it works the same way on 26.

What to Check Before You Upgrade

Node.js 26 removes a handful of things that were deprecated long ago. Most applications will never notice, but a quick search of your code and dependencies before the move is cheap.

Change in Node.js 26Who it affectsWhat to do
http.Server.prototype.writeHeader() removedOlder HTTP codeUse writeHead()
Legacy _stream_readable, _stream_writable and related modules removedVery old packages that import themImport from node:stream instead
--experimental-transform-types flag removedTypeScript with enums or namespaces run through that flagCompile first, or run through a loader such as tsx
module.register() warns at runtimeCustom module loadersMove to module.registerHooks()
NODE_MODULE_VERSION is now 147Native addons built for an older versionReinstall dependencies so addons rebuild
Linux binaries need libatomicHosts that install the official tarballInstall libatomic1 or libatomic

Native addons deserve one more sentence. Packages built on Node-API, which covers most popular ones including bcrypt and sharp, are not tied to that version number and keep working. Older addons compile on install, so a clean npm ci on Node.js 26 rebuilds them, as long as your image has a build toolchain.

The libatomic Note, Explained

The release announcement carries one practical note for Linux. Since Node.js 25, the official Linux binaries are linked against libatomic, a small runtime library that comes with GCC. Official Debian and Ubuntu container images do not include it, and neither do many minimal servers. When it is missing, Node.js installs without complaint and then refuses to start.

node: error while loading shared libraries: libatomic.so.1: cannot open shared object file: No such file or directory

The fix is one package.

# Debian and Ubuntu
sudo apt-get install -y libatomic1

# Fedora, RHEL and compatible systems
sudo dnf install -y libatomic

The official node Docker images install it for you, so FROM node:26 works as it is. The note matters mostly for teams that unpack the tarball onto their own base image or a bare server, which is common for CI runners and hand-built images. Removing the dependency is being discussed upstream, though the maintainers have said it will not make the first LTS release.

Docker, Lambda and CI

Docker images

The node:lts tag now points to Node.js 26, and there is a second change folded into it. The default Debian base for node:26 is Trixie, while node:24 used Bookworm. A Dockerfile that starts with FROM node:lts will pick up a new Node.js major and a new Debian release on its next build. That is fine when planned and confusing when it arrives inside an unrelated deploy. Pin both, for example node:26-trixie-slim or node:24-bookworm-slim, and move them on purpose.

AWS Lambda

The nodejs26.x runtime has been in public preview since August. AWS lists November 2026 as the target for general availability and asks that preview runtimes stay out of production until then. Functions created on the preview keep the same identifier when it graduates, so testing now costs nothing later. Functions on nodejs24.x are supported until April 30, 2028. If you still have functions on nodejs20.x, our note on the Lambda Node.js 20 dates explains what applies to them.

CI pipelines

The easiest first step is adding 26 to your test matrix next to the version you run today. A failure there costs nothing and tells you exactly what to fix.

strategy:
  matrix:
    node-version: [24, 26]
steps:
  - uses: actions/checkout@v7
  - uses: actions/setup-node@v7
    with:
      node-version: ${{ matrix.node-version }}
  - run: npm ci
  - run: npm test

A Steady Rhythm From Node.js 27

The October releases also start a new way of shipping Node.js. Until now there were two major versions a year, and only the even-numbered ones became LTS. From Node.js 27 there will be one major release a year, every release becomes LTS, and the version number follows the calendar. Node.js 27 arrives in April 2027 and Node.js 28 in April 2028.

Each line now passes through three stages. An alpha runs from October to March, while breaking changes are still allowed. A Current phase from April to October gives time to stabilise. Then come 30 months of LTS. The project's reasons are practical. Odd-numbered releases saw little real use, the odd and even split confused newcomers, and keeping security fixes flowing to four or five lines at once was a heavy load for a team made up mostly of volunteers.

For your team the result is a fixed calendar. A new LTS lands every October and lives for three years from its first release, so upgrading every year or two keeps you on supported ground with room to spare.

The first alpha of Node.js 27 came out on October 29. It is meant for library authors and CI pipelines, not production, and the project asks teams to run it in CI early so problems surface before release. It already hints at what to plan for next year. When --max-old-space-size is not set, the default heap limit becomes half of physical memory, kept between 256 MB and 4 GB, and memory held by Buffer and ArrayBuffer starts counting toward it. Services that depend on today's defaults should plan to set the limit explicitly. Alpha details can still change before April.

A Calm Upgrade Plan

For most teams, moving from 24 to 26 is a short project. A sensible order looks like this.

  1. Find every place a Node.js version is set, including Dockerfiles, .nvmrc, the engines field in package.json, CI configuration, Lambda runtimes and server packages.
  2. Add Node.js 26 to CI next to your current version and fix whatever fails.
  3. On Linux hosts and custom images, install libatomic before the first deploy.
  4. Run a clean npm ci so native addons match the new version.
  5. Deploy to staging, watch memory and error rates for a few days, then roll out.
  6. Pin the exact version you tested, such as node:26.13.0-trixie-slim, and update it deliberately with each patch release.

Three commands cover most of the first step.

node --version
grep -rn "FROM node" --include="Dockerfile*" .
grep -rn "node-version" .github/ .gitlab-ci.yml 2>/dev/null

What This Means for Your Team

Node.js 26 is ready for production today and will get fixes until April 2029. Nothing forces a move this month, which makes it the best time to plan one. Put 26 in your CI matrix, check the libatomic and Docker details above, and pick a week for the switch.

If you would rather hand it over, we look after infrastructure for teams that run Node.js on servers, in containers and on Lambda, and a runtime upgrade is one of the most common tasks we take on. We scope it first and agree the price before anything changes. For the security side of this month's Node.js news, see our note on the October 21 security releases.

Sources

Or read how we handle it in Infrastructure Management.