Node Upgrade Skill
LTS migration steps and breaking-change matrix - an Agent Skill for upgrading Node.js backend fleets to 24.18.0 (Active LTS).
What This Skill Does
From current LTS version and repo layout, produces:
- Breaking-change matrix per service
- Ordered PR checklist (tooling → CI → Docker → runtime)
- Verification commands per stage
- Rollback plan with image tags and timeline
When to Invoke
- Node 20 LTS approaching EOL and platform mandates 24
- New hire found
.nvmrcsays 18 while Docker uses 22 - Native addon build failures after base image bump
- Monorepo needs coordinated multi-service upgrade
Inputs
| Input | Why |
|---|---|
| Current Node version(s) | May differ per legacy service |
| Target version | 24.18.0 Active LTS |
| Repo count | Monorepo vs many repos |
| Native deps | bcrypt, sharp, canvas need rebuild |
| Deploy platform | k8s, ECS, Fly, bare VM |
Outputs
- Breaking-change table (OpenSSL, fetch, test runner, ESM)
- PR sequence with owners
- CI matrix update (
node-version: [24.18.0]) - Dockerfile
FROM node:24.18.0-alpinediff - Staging soak checklist (24-48h)
- Rollback commands
Guardrails
- Upgrade tooling before app code - CI green on new Node before merging runtime changes.
- Never mix Node versions in one deployable artifact.
- Rebuild native modules - delete
node_modulesand lockfile regen if ABI errors appear. - Run
npm auditafter reinstall - resolution may shift. - Soak staging with production traffic shadow when possible.
- Keep previous Docker tag deployable for 7 days.
Recipe
Quick-reference recipe card - copy-paste ready.
# Phase 1 - local smoke on target LTS
fnm install 24.18.0 && fnm use 24.18.0
node -v # v24.18.0
rm -rf node_modules
npm ci
npm run typecheck
npm test
npm run build
# Phase 2 - CI matrix (excerpt)
# .github/workflows/pr-checks.yml
# node-version: '24.18.0'
# Phase 3 - Docker
# FROM node:24.18.0-alpine
# Phase 4 - production verify
kubectl set image deploy/orders-api orders-api=orders-api:node24-abc123
kubectl rollout status deploy/orders-apiBreaking-Change Matrix (20 → 24)
| Area | Risk | Action |
|---|---|---|
| ESM default | require() in new files | Ensure "type": "module" or .cjs suffix |
| OpenSSL 3 | Legacy TLS ciphers | Test outbound HTTPS to old partners |
| fetch stable | Duplicate undici | Remove redundant node-fetch dep |
| Permission model | Rare sandbox use | Audit --experimental-permission flags |
| Native addons | ABI mismatch | npm rebuild or bump package version |
| Vitest/Jest | Pool config | Update to versions supporting Node 24 |
url.parse | Deprecation warnings | Migrate to URL constructor |
Working Example: Monorepo PR Order
## Upgrade PR train (Node 24.18.0)
PR1 [platform] - .nvmrc, engines, GitHub Actions node-version
PR2 [docker] - All Dockerfile FROM lines
PR3 [service-a] - Fix test timeouts exposed on 24
PR4 [service-b] - Rebuild sharp after ABI bump
PR5 [docs] - CONTRIBUTING.md, runbooks
Soak: staging 48h, watch p95 latency and error rate
Rollback: kubectl rollout undo deploy/orders-api// package.json (every workspace root and service)
{
"engines": {
"node": "24.18.0",
"npm": ">=10.0.0"
}
}# .nvmrc
24.18.0Example Prompts
Use Node Upgrade Skill:
- Current: Node 20.18.0 across 4 services in npm workspaces monorepo
- Target: 24.18.0
- Native deps: bcrypt in auth-api, sharp in media-worker
- Deploy: EKS with Helm
- Output: PR train + breaking-change matrix + rollbackFAQs
Big bang or rolling per service?
Rolling per service in monorepos after PR1-2 land platform-wide. Lower risk than upgrading all handlers same hour.
Skip odd-numbered current releases?
Always target Active LTS only for production. Odd releases are for early adopters, not fleet upgrades.
Related
- Node.js Release & LTS Policy - what production may run
- Installing & Version Management - fnm/nvm
- engines & engine-strict - enforce locally
- Before/After Node 20→24 LTS Upgrade - case study
Stack versions: This page was written for Node.js 24.18.0 (Active LTS), npm 10+, TypeScript 5.6+, Express 5, Fastify 5, and NestJS 11.