Languages

How to Upgrade to Node.js 26 Before It Goes LTS on October 28

Node.js 26 becomes the long-term support line next week, and Node 24 has just moved to maintenance. Here is what breaks, what is new, and a safe rollout order.

Tyler Brennan

Runtime & Language Tooling Writer

Published 7 min read
Open laptop displaying code on desk in bright, modern office setting. Ideal for tech and remote work context.
On this page 9 sections

Node.js 26 moves to long-term support on October 28, 2026, and Node.js 24 entered maintenance on October 20. To upgrade, test your services on Node 26 now, fix removed APIs such as the legacy stream modules, run your suite in CI on both versions, then roll out gradually. Treat the LTS date as your deadline to be ready.

Backtrace covers the tooling that decides how fast engineering teams ship, and runtime upgrades sit near the top of that list. This guide is for developers and platform engineers who run Node services in production. It covers the schedule, the breaking changes that matter, a six-step plan and how to test before you commit.

What Does the Node.js 26 LTS Schedule Mean for You?

Close-up shot of a hand marking a date on a calendar with a pen, emphasizing planning and scheduling.

It means Node 26 is the version to target for new production work from October 28, while Node 24 stops getting new features. The official Node.js release schedule lists Node 26 starting May 5, 2026, entering LTS on October 28, 2026 and ending on April 30, 2029. Node 24 enters maintenance on October 20, 2026.

The Node.js previous releases page also notes that production applications should only use Active LTS or Maintenance LTS releases. Until the 28th, Node 26 is labeled Current. Odd-numbered Node 25 has already reached end of life, so teams that jumped on it need to move anyway.

Maintenance status is not a crisis. Node 24 still receives critical fixes. But you gain more time and better support by planning the move now instead of during an incident.

What Changed in Node.js 26

The release notes for Node.js 26.0.0 list a few headline changes. The most visible is that the Temporal API is on by default. Temporal is a modern date and time API meant to replace the error-prone legacy Date object.

V8 moved to version 14.6, which matches Chromium 146. That adds Map upsert helpers such as getOrInsert and getOrInsertComputed, plus Iterator.concat for joining iterators. The built-in fetch client also moved to Undici 8.0.2.

None of these features forces a code change. They are optional upgrades you can adopt after the move. The breaking changes are the part that needs attention first.

Which Breaking Changes Are Most Likely to Hit You?

Close-up of PHP code on a monitor, highlighting development and programming concepts.

Removed APIs and build requirements are the likeliest causes of failures. The table below lists the changes from the release notes that most often affect application teams, with the usual fix for each.

Which Breaking Changes Are Most Likely to Hit You?
ChangeWho it affectsTypical fix
http.Server writeHeader removedOlder HTTP codeUse writeHead instead
Legacy _stream_* modules removedOld libraries that deep-importImport from the stream module; update the dependency
--experimental-transform-types removedTypeScript-in-Node usersUse a build step or another loader
module.register() deprecated at runtimeCustom loader setupsPlan a migration; expect warnings
NODE_MODULE_VERSION is 147Native addonsRebuild every addon
Python 3.9 and GCC below 13.2 unsupportedTeams that build Node or addons from sourceUpdate the build image

Other behavior changes are smaller but worth a scan. Readable streams now read one buffer at a time, and localStorage returns undefined when no file is configured. The assert module also accepts printf-style messages.

Native addons deserve special attention. A new module version means any compiled dependency needs a rebuild or a new prebuilt binary. A single stale addon can stop a container from starting.

How to Upgrade to Node.js 26 in Six Steps

Follow this order to keep each step small and reversible:

  1. Inventory every place Node runs: services, CI images, build tools and developer machines.
  2. Pin the current version in an engines field and a version file so everyone tests the same runtime.
  3. Add Node 26 to your CI matrix next to your current version.
  4. Fix what fails, starting with removed APIs and rebuilt native addons.
  5. Deploy to a low-risk service first and watch error rates and memory for a week.
  6. Roll through the remaining services, then update base images and drop Node 24 from CI.
Close-up view of a developer typing code on a keyboard with a computer screen showing scripts.

The matrix step does most of the work. If your pipeline already runs several versions, the cost is a single line. If it does not, our comparison of GitHub Actions and GitLab CI covers how each handles version matrices.

Pick the pilot service carefully. A good candidate has solid test coverage, modest traffic and an owner who will watch dashboards. An internal tool or a background worker is better than the checkout path. If the pilot week is quiet, you have real evidence for the bigger services.

Keep rollback easy. Build images for both versions and tag them clearly. A one-line revert beats a night of debugging.

How Do You Test an Upgrade Without Surprises?

Test beyond unit tests, because runtime upgrades break integration points. Run your full test suite on Node 26, then run a staging environment with real traffic replays. Watch for changed stream behavior, different error messages and slower cold starts.

A short test plan helps. Check these areas in order:

  • Install: does a clean install work with your lockfile and package manager?
  • Build: do bundlers, compilers and native addons build without warnings?
  • Run: do services start, and do health checks pass?
  • Load: do latency and memory match the old runtime under the same traffic?

Dependencies are the common failure source. Our package manager speed comparison is a useful companion, since reinstalling from scratch is part of any upgrade. Update dependencies that deep-import internal Node modules before you switch.

Supply chain hygiene fits this window too. Regenerating your lockfile is a good time to produce a fresh software bill of materials, as covered in our SBOM generation how-to.

Common Failures and What They Usually Mean

Most upgrade failures fall into a few patterns, and recognizing them saves hours. Use this list to match a symptom to its likely cause:

  • A crash on startup that mentions a native module usually means an addon was built for an older module version.
  • A "cannot find module" error for a stream path points to a library that deep-imports a removed underscore module.
  • A TypeError on writeHeader means old HTTP code that needs writeHead.
  • A build failure in a container often traces back to an old Python or compiler in the image.
  • New deprecation warnings in logs usually come from loader hooks that call module.register().

The first two are the most common in practice. Both are dependency problems, not application bugs. The fix is usually to upgrade the package, not to patch your own code.

It helps to run Node with warnings turned into errors in a test job. That surfaces deprecations early, while you still have time to plan. Treat each warning as a ticket with an owner, not as noise to filter out of the logs.

Finally, check your tooling versions. Linters, bundlers and test runners sometimes pin an older Node range in their own configuration. Update those ranges when you update the runtime so developers get the same behavior locally and in CI.

Should You Adopt Temporal Right Away?

No, adopt it deliberately. Temporal is available without a flag in Node 26, but your dependencies, ORMs and date libraries may not understand Temporal objects yet. Using it at the edges of new code is safe. Replacing every Date in a large codebase in one pass is not.

Four wall clocks showing different time zones for London, New York, Tokyo, and Moscow.

A sensible approach is to start with new modules and keep existing Date handling. Write small adapters at the boundary, where data enters or leaves your code. Over time, the adapters shrink as libraries catch up.

Our read at Backtrace is that teams get the best return from Temporal in scheduling, billing and reporting code. Those areas suffer most from time zone and daylight-saving mistakes.

What If You Cannot Upgrade Yet?

Stay on Node 24 for now, but set a date. It remains supported in maintenance, and a short delay is reasonable if a critical dependency lags. Do not stay on an end-of-life version. Node 25 and Node 20 are both listed as end of life on the official releases page.

Also decide what you will do about libraries that never update. If a dependency is abandoned and breaks on Node 26, replace it rather than freezing your runtime for it. One stale package should not set the pace for the whole stack.

Document the blockers. A written list of the addon, library or build tool holding you back makes the decision visible. It also gives you something concrete to chase upstream.

Two developers examining code on a large screen in a modern office space, focusing on web development.

Conclusion

Node.js 26 is ready to become the standard line on October 28. The main work is removing old API use, rebuilding native addons and proving the change in CI. The new features, including Temporal and the updated V8 and Undici, can wait until the migration is stable.

This week, add Node 26 to your CI matrix and read the failures. Fix the removed APIs first, then plan a staged rollout. Backtrace will keep tracking runtime releases as the LTS date arrives.

When does Node.js 26 become LTS?
According to the official Node.js release schedule, Node.js 26 enters long-term support on October 28, 2026. It was first released on May 5, 2026, and is scheduled to reach end of life on April 30, 2029. Until the LTS date, it is labeled as the Current release.
Is Node.js 24 still supported after October 20, 2026?
Yes. Node.js 24 moved from Active LTS to Maintenance LTS on October 20, 2026, and its scheduled end of life is April 30, 2028. Maintenance means critical bug fixes and security updates continue, but new features stop. Production teams can stay on it while they test the move to Node 26.
What are the biggest breaking changes in Node.js 26?
The most disruptive changes are the removal of http.Server writeHeader, the legacy underscore stream modules and the experimental transform-types flag. Native addons also need a rebuild because the module version is now 147. Teams that build from source need Python 3.9 dropped and GCC 13.2 or newer.
Does Node.js 26 include the Temporal API?
Yes. Temporal is enabled by default in Node.js 26, without a flag. It is a modern replacement for the legacy Date object. Many libraries and ORMs may not support Temporal objects yet, so most teams should adopt it gradually in new code rather than rewriting existing date handling all at once.

Written by

Tyler Brennan

Runtime & Language Tooling Writer

11+ years experience

Tyler spent nine years as a full-stack engineer at a mid-sized e-commerce company, where he owned the Node.js services and the build pipeline behind them. He ran four major runtime upgrades there and still keeps the habit of reading changelogs for what gets removed before what gets added. At Backtrace he covers language releases, package managers and the local tooling that decides how fast a team moves. His rule is simple: an upgrade guide is only useful if it lists the failure you will see first and the command that finds it.

Credentials

  • B.S., Computer Science, University of Wisconsin-Madison
  • Former Senior Full-Stack Engineer, e-commerce platform (2014-2023)
  • OpenJS Foundation Node.js Application Developer certification