VVersions.dev

Node.js 18 → Node.js 24

Node 18 reached end-of-life on 2025-04-30 and receives no security patches, so moving to the active Node 24 LTS is urgent. You can go directly to 24 — skipping 20 and 22 — but the three-major gap (18 → 20 → 22 → 24) means a larger ABI jump for native modules and more removed/deprecated APIs to clear.

Version upgradeDifficulty: hardEffort: 2–5 dayshigh risk

Last verified · Updated May 22, 2026

Node 18 is end-of-life (since 2025-04-30) — unpatched and a security liability — so this upgrade is urgent. Go directly to the Node 24 LTS; there is no need to stop at 20 (also EOL) or 22. The three-major gap means a larger ABI jump for native modules and more deprecated APIs to clear than a single-step move, which is why this path is rated higher risk.

Should you upgrade directly?

Yes — go straight to Node 24. Stopping at Node 20 lands you on another EOL major, and Node 22 is only a maintenance LTS, so neither adds meaningful runway. The cost of skipping the intermediates is that you absorb three majors' worth of removed APIs and behavior changes in one step — the url.parse runtime deprecation, tls.createSecurePair removal, the OpenSSL 3 baseline, and (on Windows) the MSVC-to-ClangCL toolchain change.

Key differences

  • Three LTS majors of removed/deprecated APIs to clear, not one (url.parse, tls.createSecurePair, SlowBuffer, dirent.path).
  • require() of synchronous ES modules is on by default in Node 24 (unavailable on 18).
  • Stable Permission Model (--permission), global URLPattern, native .env loading, and built-in WebSocket (Undici 7).
  • Built-in fetch became stable in Node 21, so it is stable on 24 (it was experimental on 18).
  • A much newer V8 (13.6 vs ~10.x) and bundled npm 11.
  • Native modules must be rebuilt across a large ABI gap; on Windows, ClangCL replaces MSVC for building from source.

Files and patterns to inspect

  • engines.node in package.json and the committed .nvmrc / .node-version.
  • The node-version matrix in .github/workflows/*.yml and the Docker base image (FROM node:18...).
  • Dependencies with native bindings that need rebuilding across three majors.
  • Crypto/TLS code that relied on pre-OpenSSL 3 defaults or tls.createSecurePair.
  • Code using url.parse(), SlowBuffer, or other APIs deprecated across Node 18–24.

Pre-migration checklist

  • Green test suite on Node 18 before starting
  • Lockfile committed; dependencies audited for Node 24 engine support
  • A dedicated upgrade branch
  • Crypto/TLS and url.parse usage inventoried for review

Official sources

Copy-ready AI prompts

Structured prompts for an AI coding assistant. Inspect first, then execute incrementally, and keep a human in the review loop.

Repo inspection: Repo inspection prompt

You are helping with a Node.js migration: Node.js 18 to Node.js 24.

Do not edit files yet. First inspect the repository and report:
1. The current Node version targets: the "engines.node" field in package.json, the .nvmrc / .node-version file, and the node-version used in CI (.github/workflows/*.yml) and any Dockerfile base image.
2. The module system: whether package.json sets "type": "module", and the mix of .js / .cjs / .mjs files.
3. Native modules (packages with binding.gyp or install scripts) that must be rebuilt against the new ABI.
4. Usage of deprecated or removed APIs surfaced by the new major's deprecations (e.g. legacy url.parse patterns, the old assert API, removed crypto/buffer constructors).
5. The install, build, and test commands and whether the lockfile is committed.

Return: a risk summary, the highest-risk files and dependencies, a suggested migration order, the commands to run before editing, and any questions that need human confirmation.

Safety: Inspection only. The agent must not modify files in this step.

Works with Claude Code, Cursor, GitHub Copilot.

Migration execution: Migration execution prompt

Perform the migration (Node.js 18 to Node.js 24) one concern at a time.

Work in this order and pause for review after each: (1) bump "engines.node" in package.json and pin the new version in .nvmrc, (2) update every CI matrix entry and Docker base image to the new Node version, (3) reinstall and rebuild native modules with `npm rebuild`, (4) run the test suite and triage runtime failures, (5) replace any deprecated/removed APIs surfaced during inspection.

After each step run the project's install and test commands and report results before continuing. Do not bundle unrelated refactors or upgrade dependencies that are not required by the Node bump.

Safety: Apply changes incrementally and keep each step reviewable. Rebuild native modules before assuming a failure is a code problem.

Works with Claude Code, Cursor, GitHub Copilot.

Test plan

Commands

  • node --version
  • npm ci
  • npm rebuild
  • npm test
  • npm run build

Manual checks

  • Native modules: confirm packages with native bindings load without ABI/version errors at runtime.
  • Startup: boot the app on the new Node version and watch for new deprecation warnings.
  • Globals: verify code relying on built-in fetch, the test runner, or other newly-stable APIs behaves the same locally and in CI.

Regression risks

  • Native addons compiled against the old ABI failing to load until rebuilt.
  • Deprecated APIs removed in the new major breaking code paths not covered by tests.
  • Dependencies that declare an engines range excluding the new Node version.

Acceptance criteria

  • Install, build, and the full test suite pass on the target Node version.
  • CI, .nvmrc, and the Docker image all reference the same Node version.
  • No new Node deprecation warnings appear in the test output.

Frequently asked questions

Should I stop at Node 20 or 22 on the way to 24?

No. Node 20 is end-of-life (so it would be a second migration you immediately have to redo), and Node 22 is only a maintenance LTS. Go directly to the active Node 24 LTS unless a critical dependency is not yet Node 24-ready, in which case pin Node 22 as a temporary stopgap.

Why is 18 → 24 rated higher risk than 20 → 24?

It crosses three LTS majors instead of two, so you absorb a larger native-module ABI jump and more removed/deprecated APIs (across 18, 20, 22, and 24) in a single step. Inspect carefully and migrate one concern at a time.