TechEarl

Node.js LTS vs Current: Which Version Should You Use?

Node LTS vs Current explained: what the even/odd version lines mean, the 30-month support window, when Current is worth it, and how to pick the right line for production, libraries, and CI.

Ishan Karunaratne⏱️ 12 min readUpdated
Share thisCopied
Node.js LTS vs Current explained: release lines, the 30-month support window, and which version to run in production

For almost everything you ship, the answer to Node LTS vs Current is: run the latest LTS (Long Term Support) line, not Current. LTS is the even-numbered major (20, 22, 24, ...), released every April, with a 30-month LTS support window, and it is what every library on npm tests against first. Current is the odd-numbered major (21, 23, 25, ...) released every October, supported for only 6 months, and it exists to road-test new V8 and runtime features before they graduate into the next LTS. Pick Current only when you specifically need a feature that has not landed in LTS yet, or you are testing your own code against the next line early. The card below shows the exact versions both lines are on right now.

Current Node.js
26.2.0

Latest release with newest features. Best for experimentation.

Latest LTS
24.16.0

Long-Term Support — the version to use in production.

What is the difference between Node LTS and Current?

Node.js cuts a new major version every six months. Each one starts life in the Current release line, where it gets active feature work, new V8 versions, and API changes for roughly six months. After that:

  • Even-numbered majors (20, 22, 24) transition into LTS in October of the year they were released. From there they get 12 months of "Active LTS" (bug fixes, selected backports) followed by 18 months of "Maintenance LTS" (critical and security fixes only). That LTS window is the "30 months of support" Node advertises, counted from the day the line enters LTS; add the ~6 months it spent as Current first and a single major is alive for roughly three years end to end.
  • Odd-numbered majors (21, 23, 25) never become LTS. They go end-of-life roughly when the next even major ships, so their useful life is about 6 months.

So "Current" is always the newest release line that is still receiving feature work, whether that is an even major in its first six months or an odd major in its entire lifetime. "LTS" is the even line once it has stabilised. The practical takeaway: an even major is Current for its first ~6 months, then LTS for ~30 more. An odd major is Current and nothing else.

Jump to:

Node LTS vs Current at a glance

LTS (Active)LTS (Maintenance)Current
Version numbersNewest even major (22, 24, ...)Previous even majorNewest line (even under 6mo, or odd)
ReleasedApril(rolled in from Active)April (even) / October (odd)
Support window~12 months active~18 months after that~6 months total
What it getsBug fixes, safe backportsCritical + security fixes onlyActive feature work, V8 bumps, API changes
Use forProduction, published libraries, CI baselineExisting prod mid-migrationTrying new features, testing the next LTS early
StabilityHighHighest (frozen API)Lower (APIs can change)

If you take one row away: production runs Active LTS, libraries target Active LTS, and you only touch Current on purpose.

The release schedule, in plain terms

The Node.js release schedule is a fixed calendar, which is the whole point of it. You can plan upgrades years ahead because the dates do not move:

  • April: a new even major releases (this is the next LTS line).
  • October: that same even major is promoted from Current to Active LTS, and a new odd major releases as the new Current.
  • The following April: another even major releases, the previous Active LTS drops to Maintenance, and the odd major from last October starts winding down to end-of-life.

A concrete walk-through with Node 22:

code
2024-04   Node 22 releases (Current)
2024-10   Node 22 -> Active LTS;  Node 23 releases (Current)
2025-04   Node 24 releases (Current);  Node 22 still Active LTS
2025-10   Node 24 -> Active LTS;  Node 22 -> Maintenance LTS;  Node 25 (Current)
2027-04   Node 22 -> End of Life (~30 months after release)

Odd majors (21, 23, 25) appear in this timeline only as short-lived Current releases. They never get an LTS row. That is by design: they are the proving ground for features that, if they survive, ship in the next even major.

For the exact end-of-life dates of every line, the previous releases table on nodejs.org is the authoritative source. The live card at the top of this page reads the same release feed.

When LTS is the right choice (almost always)

Run LTS when:

  • You are shipping to production. A 30-month support window means you can stay on a single major for over two years without scrambling for security patches. Current gives you six months before you are forced to upgrade.
  • You are publishing a library to npm. Your engines.node range should target LTS, because that is what your consumers run. Testing only against Current means you can ship code that breaks on the version most of your users are actually on.
  • You want a stable API surface. Active LTS gets backported bug fixes but not breaking API changes. Current can change behaviour between minor releases as features mature.
  • You run anything you do not babysit. Cron jobs, internal tools, that one box in the corner. LTS means it keeps getting security fixes without you re-upgrading twice a year.

This is also why every official Docker convenience tag and most CI defaults point at LTS. node:lts-alpine tracks the current Active LTS, and actions/setup-node with lts/* resolves to the same. The ecosystem assumes LTS unless you say otherwise.

When Current is actually worth it

Current is not a trap, it is a tool with a narrow use case. Reach for it when:

  • You need a feature that has not reached LTS yet. A new V8 capability, a stabilised core API, a flag that flipped to default. If the feature is in Current but not in the latest LTS, Current is your only option short of waiting for the next April.
  • You are testing your own code against the next LTS, early. Running your test suite on Current in CI surfaces breakage months before that line becomes LTS and you are forced onto it. This is the most defensible production-adjacent use: a node-version: [22.x, 24.x, 26.x] matrix where the newest entry is Current.
  • It is a personal or throwaway project. No paying users, no support obligation. Run whatever is newest if you like living on the edge.

The cost is the re-upgrade treadmill. An odd Current major goes end-of-life in about six months, so anything you stand up on it needs migrating off before then. For production that is a recurring chore you imposed on yourself for no benefit; for a CI canary it is exactly what you wanted.

How to check and install each line

Check what you are on first:

bash
node --version    # e.g. v22.11.0  -> even major -> an LTS line

An even major number means you are (or will be) on an LTS line. An odd major number means Current, with a short support clock.

Install the latest LTS with whatever manages your Node:

bash
nvm install --lts            # nvm: latest LTS
fnm install --lts            # fnm: latest LTS
volta install node@lts       # Volta: latest LTS

Install Current (the absolute newest release) when you actually want it:

bash
nvm install node             # nvm: "node" alias = latest Current
fnm install latest           # fnm: latest Current
volta install node@latest    # Volta: latest Current

In Docker, the tag encodes the choice:

dockerfile
FROM node:lts-alpine     # tracks the current Active LTS
FROM node:current-alpine # tracks Current; flips majors twice a year
FROM node:22-alpine      # pin a specific major (recommended for prod)

Pinning a specific even major (node:22-alpine) is better than node:lts for production, because lts itself moves to the next major every October and a base-image flip should be a deliberate commit, not a surprise on a rebuild. For the full set of upgrade commands across version managers, OS package managers, Docker, and CI, see my guide on how to update your Node.js version. If you are starting from nothing, installing Node.js from scratch walks through getting the first version on the box.

What "Active" vs "Maintenance" LTS means for you

Once an even major becomes LTS, it spends time in two phases, and the difference matters when you are deciding how long to sit on a version:

  • Active LTS (~12 months): receives bug fixes and selected non-breaking feature backports. This is the sweet spot for production: stable but still actively curated.
  • Maintenance LTS (~18 months): receives only critical bug fixes and security patches. The API is effectively frozen. Fine to stay on while you plan a migration, but you are on a line that is winding down.

The practical rule I use: deploy on Active LTS, and start planning the jump to the next Active LTS when your current line drops to Maintenance (every October). That gives you roughly 18 months of runway to migrate before end-of-life, which is plenty unless you have a lot of native modules to rebuild. The one thing you do not want is to discover at end-of-life that you are still on a version with no security backports left.

LTS, Current, and CI matrices

CI is where the LTS-vs-Current question gets the most nuanced answer, because you can test more than one line at once. A sensible matrix tests every LTS in active support plus, optionally, Current as a forward-looking canary:

yaml
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [22.x, 24.x]   # every LTS line still in support
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'
      - run: npm ci
      - run: npm test

Add Current (the newest line still in feature work, e.g. 26.x) as a non-blocking matrix entry if you want early warning about the next LTS, and mark it continue-on-error: true so a Current-only breakage does not fail the whole build. You can also let the action resolve the line by name instead of a number:

yaml
- uses: actions/setup-node@v4
  with:
    node-version: 'lts/*'    # latest Active LTS, resolved by the action

The actions/setup-node action understands lts/*, lts/-1 (one LTS back), and current, so you can express the policy without hardcoding a number that goes stale every six months. For libraries, your blocking matrix should cover every LTS your engines.node range claims to support; Current belongs in the canary lane, not the gate.

FAQ

See also

  • How to update your Node.js version: every reliable upgrade route across nvm, fnm, Volta, the official installer, OS package managers, Docker, and GitHub Actions, with the native-module rebuild step most guides skip.
  • Installing Node.js from scratch: getting the first version on a fresh machine, choosing between a version manager and a direct install, and verifying it worked.

Sources

Authoritative references this article was fact-checked against.

TagsNode.jsJavaScriptLTSVersion ManagementRelease ScheduleDevOpsCI/CD

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Tech Architect · Software Engineer · AI/DevOps

Tech architect and software engineer with 20+ years building software, Linux systems, and DevOps infrastructure, and lately working AI into the stack. Currently Chief Technology Officer at a healthcare tech startup, which is where most of these field notes come from.

Keep reading

Related posts

find vs locate vs mlocate: Which File Search Tool to Use

find walks the live filesystem every time it runs: always current, sometimes slow. locate queries a prebuilt database: instant, but stale until the next updatedb. This breaks down the locate family (mlocate, plocate, slocate), the macOS situation, and exactly when to reach for each one.

grep vs ripgrep vs ag: Which Search Tool to Use

grep is on every system and searches exactly what you point it at. ripgrep (rg) is the fast Rust-based default for code search: it skips .gitignore'd, hidden, and binary files unless told otherwise. ag (the_silver_searcher) was the older fast-grep, now largely superseded by ripgrep. This breaks down speed, defaults, regex engines, and exactly when to reach for each one.