LTS vs Current Releases
Node.js ships new versions on a predictable schedule, split into two tracks: Current and LTS (Long-Term Support). Knowing the difference — and the cadence behind it — tells you which version to run in production, which to experiment with, and when you must upgrade before security patches stop.
How version numbers work
Node follows semantic versioning: MAJOR.MINOR.PATCH (e.g. 20.11.0). The key rule that drives the whole release model: even-numbered majors become LTS; odd-numbered majors never do.
Part | Bumped when | Example |
|---|---|---|
MAJOR | Breaking changes; new release line |
|
MINOR | New backward-compatible features |
|
PATCH | Bug & security fixes only |
|
The release lines
Current — the newest line, with the latest features. A new major ships roughly every 6 months. Odd-numbered majors (19, 21…) stay Current then go straight to end-of-life — never use them in production.
Active LTS — even-numbered majors (18, 20, 22…) that have stabilized. The default for production.
Maintenance LTS — an older LTS line receiving only critical and security fixes before reaching end-of-life.
End-of-Life (EOL) — no more updates, including security fixes. Never run EOL versions anywhere exposed.
The lifecycle
Phase | Who it is for | Updates received |
|---|---|---|
Current | Early adopters, library authors | New features + fixes |
Active LTS | Production apps | Bug + security fixes (no breaking changes) |
Maintenance LTS | Apps planning an upgrade | Critical + security fixes only |
EOL | Nobody — upgrade now | None (insecure) |
A major starts as Current for ~6 months. Even majors then enter Active LTS (~12 months) and finally Maintenance (~18 months) — roughly 30 months of total support from release. This predictability is the point: teams can plan upgrades years ahead.
Which one should you use?
Building a product / API? → Active LTS.
Writing a library? → Test against all supported LTS lines and Current, so you support the widest range of users.
Trying a brand-new language feature? → Current, on a throwaway branch only.
Declaring the version your project needs
Communicate the required version in two places so both humans and tooling agree:
.nvmrc — for nvm/fnm and CI
20.11.0
package.json — npm warns (or errors) on mismatch
{
"engines": {
"node": ">=20.0.0 <21.0.0"
}
}Checking what you are running
node -v # the line you are on, e.g. v20.11.0 node -p "process.versions" # versions of V8, libuv, OpenSSL, etc.
{
node: '20.11.0',
v8: '11.3.244.8-node.17',
uv: '1.46.0',
openssl: '3.0.12+quic'
}