Skip to content

Node.js revisited a decade-old release plan. What survived?

Revisiting a ten-year-old policy is not the same as throwing it out — it means checking which assumptions still hold and changing only the parts that have stopped working.

On March 10, 2026, the Node.js Releasers Working Group published “Evolving the Node.js Release Schedule” — the first real change to how the project ships releases since its original LTS plan was written in 2015.

Starting with Node.js 27 (first Alpha October 2026, first stable April 2027), the project will cut one major per year instead of two. The decade-old odd-vs-even split is gone: every annual major becomes LTS in October. A new Alpha channel takes over the early-testing job that odd-numbered “Current” lines used to do.

What did not change is also worth naming. The 30-month LTS window stayed. The 6-month overlap between successive LTS lines stayed. The cap on concurrent lines stayed at three. The proposal that opened this whole discussion — filed July 2025 — had asked for 24 months of LTS. After eight weeks of debate, the proposer pulled back to thirty.

This is what happens when a project revisits a ten-year-old policy and finds that most of the original plan still works.

What the 2015 plan said

James M Snell wrote the first Node.js LTS plan in July 2015, months before Node 4 “Argon” shipped as the first LTS. The shape, verbatim from the 2015-07-23 README:

“new LTS releases will occur once every 12 months… Every LTS release will be actively maintained for a period of 18 months… until the current LTS release moves into Maintenance 12 months later. (That is 18 months of active LTS + 12 months Maintenance only). There will be no more than two active LTS releases at any given time, overlapping for a maximum period of six months.”

Three numbers from that paragraph survived ten years: one new LTS line per year. Thirty months of total support per line. A six-month overlap so a team always has somewhere supported to move to.

What the document does not contain is also worth noticing. It never uses the words corporate, enterprise, adoption, or cycle. It describes mechanics without naming the audience the mechanics were designed for. That audience became explicit only ten years later — when the same author looked back on his own work.

Why the policy was revisited

On July 14, 2025, RafaelGSS opened nodejs/Release#1113 proposing annual majors and a 24-month LTS. Within an hour, Matteo Collina (TSC) replied “+1”. Twelve minutes later, the original plan’s author replied to his own ten-year-old work.

@jasnell View on GitHub →

When I first proposed the current plan a decade ago it was based entirely on corporate adoption cycles that were relevant at that time and we really haven’t revisited the plan since.

This is the comment everything else happened against. The original author named, on the public record, the assumption his plan had been built on top of: corporate adoption cycles. The 2015 README never said that. The 2025 retrospective did. In the same comment, the author asked the project to keep the six-month overlap — the part of his plan that lets large organizations move between LTS lines without ever running an unsupported version.

The gap is the case in miniature. The author was willing to drop the cadence he chose in 2015, but argued the migration window his plan made room for was still doing real work.

A second voice the same day put the maintainer-cost case plainly:

@marco-ippolito View on GitHub →

Backporting to old release lines is HARD so having a shorter lifespan makes releasers life easier.

Annual majors had instant agreement. LTS duration did not.

  1. jasnell drafts the original LTS plan: 30 months of total support, six-month overlap, two concurrent lines.
  2. RafaelGSS opens #1113 — annual majors, 24-month LTS.
  3. richardlau (IBM) reports IBM/Red Hat downstream prefer 30 months unchanged or longer.
  4. RafaelGSS pulls back: “30 months of LTS period and a short release cycle.”
  5. Matheus-RR (endoflife.date) reports teams running Node 21/23/25 in production assuming they’re LTS.
  6. Issue #1113 closes. Announcement blog publishes.
  7. First annual major under the new policy: 27.0.0 stable.

The proposal that didn’t ship

The 24-month LTS lasted nine days. On July 23, richardlau — IBM’s engineer on the Release WG — posted feedback gathered from internal teams at IBM and Red Hat.

@richardlau View on GitHub →

the consistent feedback is that they would prefer the support timeframes of Long Term Support releases to remain at 30 months… Our enterprise clients don’t want to/can’t move up to newer releases on a yearly basis. Current releases are ignored (since they are not LTS).

The comment is short on rhetoric and long on real numbers. It is also worth reading for what it is not. It is not a veto. It is not corporate lobbying. It is a Release WG member surfacing the real-world limits of the teams that ship audited, patched Node.js to enterprise customers — teams whose compliance audits and rollout schedules are slow on purpose.

A second strand of pushback came from inside the project:

@panva View on GitHub →

I’m also -1 on shortening the LTS, the extra 6 months is what allows users to plan for a “skip one LTS” upgrade.

The “skip one LTS” pattern — Node 18 straight to Node 22, skipping 20 — only works if the LTS being skipped is supported long enough for the next-but-one to land. Twenty-four months doesn’t leave room. Thirty does.

By September 1, the proposer had pulled back: “what if we don’t have a ‘Current’ release and have a major starting with LTS since April? This way we’ll have 30 months of LTS period and a short release cycle.” The shape that shipped is close to that, with one adjustment: the six months before LTS promotion stay as a stabilization window, still called Current. The proposer’s original 24-month figure does not appear in the final policy.

What users were doing

The case for changing the cadence had two distinct arguments. One was about maintainer load. The other was about user confusion. They did not require the same change.

@mcollina View on GitHub →

Very few users use odd releases, and we should not be planning to make them more useful.

The clearest evidence on this point came late in the discussion, from outside the project’s maintainer pool:

@Matheus-RR View on GitHub →

Teams don’t know odd releases aren’t LTS. We regularly see Node 21/23/25 in production environments where the team assumed they were on a supported release. Annual majors where every release is LTS would eliminate this entire class of confusion.

The author works on endoflife.date, which tracks end-of-life data for hundreds of products. The comment is data, not opinion. It is a report that production teams are misreading the odd/even signal, often. Documentation that says “production applications should only use Active LTS or Maintenance LTS” didn’t make it into the heads of teams running npm install -g node@latest.

The new policy answers this directly. Every annual major becomes LTS. There is no longer a stable release line that production users have to learn not to use. The early-testing job that odd-numbered Currents were meant to do moves to a separate Alpha channel — marked clearly as a prerelease (27.0.0-alpha.1), explicitly not for production.

What survived, and why

Place the new schedule next to the old one and the resemblance is hard to miss. Three numbers from the 2015 plan are still in the 2026 announcement: thirty months of LTS, six months of overlap, three concurrent lines as the maintenance ceiling.

The maintainers tried to change one of them. The 24-month proposal was a serious argument about real maintainer cost. Eight weeks of debate followed it, four explicit -1 votes from named maintainers, and the proposer himself rewrote the shape — “30 months of LTS period and a short release cycle” — before the discussion converged.

What it tells us is that the assumptions the 2015 plan was built on top of — that enterprise migration is slow, that audited downstream builds sit at least a month behind the community release, that teams need a buffer to skip an LTS without running unsupported software — are still true in 2026. IBM and Red Hat confirmed it the simplest possible way: when asked, they said the existing 30-month window was the floor, not the ceiling.

The maintainer-cost argument was real. The user-confusion argument was real. Neither argument required changing the support window. Both could be answered by changing the cadence — fewer concurrent lines, fewer release decisions, a clearer mapping between version number and support status — without touching the duration the policy provides.

The lesson

The instinct when revisiting a long-running policy is to use the revisit as license to overhaul. After ten years there is always something worth fixing, and a revisit is the rare moment when changing it is socially acceptable.

The Node.js project, ten years into its release model, kept asking which premise broke? before what do we change? — and accepted that most of the answer was already in the 2015 README.

The project filed four proposed changes. Three shipped. The one that didn’t ship is the one most affected by people outside the maintainer pool — the ones the policy was built to serve.

Further reading