Skip to content

Node 20 is past EOL (2026-04-30) and pinned fleet-wide — audit and migrate off it #78

Description

@twistedmelonman

Summary

Node 20 reached end-of-life on 2026-04-30 — four months ago. It no longer receives security patches. The local nvm default still points at it, and it is pinned across CI workflows, Dockerfiles, and manifests fleet-wide. One repo is still on Node 18 (EOL 2025-04-30) and one manifest floor allows Node 14 (EOL 2023-04-30).

This surfaced incidentally while working in an unrelated repo (gmail-newsletter-filter), where node --version reported v20.20.2 despite v22, v24, and Homebrew's v26 all being installed locally. The pin, not a missing install, is the cause.

EOL dates below are from nodejs/Release/main/schedule.json, fetched 2026-09-01.

Line EOL Status
v14 2023-04-30 past EOL
v18 2025-04-30 past EOL
v20 2026-04-30 past EOL
v22 2027-04-30 supported
v24 2028-04-30 supported (current LTS, lts/krypton)
v26 2029-04-30 supported (current line)

Local machine state

~/.nvm/alias/default contains 20. nvm prepends its active version to the front of PATH (position 1), ahead of Homebrew (position 6), so v20.20.2 shadows every other install. Nothing is missing — v22.23.2, v24.19.0, and Homebrew 26.8.1 are all present and idle.

Low-risk to change: all three nvm versions have only corepack and npm installed globally, so nothing needs reinstalling.

nvm alias default lts/krypton   # v24.19.0
hash -r                         # or open a new shell

Note: after switching, command -v node and type node will report the stale cached path from bash's hash table. Use which node to verify.

Fleet findings

Scanned ~/Developer/* local checkouts for .nvmrc, package.json engines, workflow node-version, Dockerfile bases, and volta/asdf pins.

Past EOL — Node 18:

  • tensegrity/.github/workflows/ci.yml:18 — CI matrix [18.x]

Past EOL — Node 20 in CI:

  • claude-code-workflows-agents/.github/workflows/code-quality.yml:80
  • claude-code-workflows-agents/.github/workflows/validate.yml:233
  • Gmail-MCP-Server/.github/workflows/ci.yml:171 (note: publish.yml:34,66 already on 22 — CI and publish disagree)
  • kebab-tax/.github/workflows/deploy-workers.yml:37,68,139
  • kebab-tax/.github/workflows/release-gate.yml:47
  • kebab-tax/.github/workflows/ci.yml:65,149
  • reliquarist/.github/workflows/ci.yml:31

Past EOL — Node 20 in container images:

  • kebab-tax/mobile/Dockerfile.test:2FROM node:20.18.1-alpine
  • Gmail-MCP-Server/Dockerfile:1FROM node:20-slim

Version pins in manifests:

  • kebab-tax/.nvmrc20.19.4 (also consumed by publish-changelog.yml:27 via node-version-file)
  • reliquarist/package.jsonengines.node: >=20.0.0
  • Gmail-MCP-Server/package.jsonengines.node: >=14.0.0 (floor allows three EOL lines)

Proposed actions

  1. Move the local nvm default off v20 (command above). Decide whether nvm or Homebrew is the source of truth for Node on this machine — currently both are installed and nvm silently wins.
  2. Pick a fleet target. Node 24 is the current LTS and the conservative choice; it is already installed locally.
  3. Update the CI, Dockerfile, and manifest pins listed above. kebab-tax is the largest single consumer (7 workflow pins plus .nvmrc plus a Dockerfile) and should probably move as one change.
  4. Resolve Gmail-MCP-Server's internal disagreement — CI on 20, publish on 22.
  5. Raise Gmail-MCP-Server's engines.node floor off >=14.0.0.
  6. Consider whether this warrants a recurring check. An EOL runtime is a slow-moving security exposure that nothing currently alerts on — this was found by accident, not by a control.

Verification notes

  • Scan covers local checkouts only under ~/Developer. Repos not checked out locally, or checked out elsewhere, were not scanned.
  • No volta or asdf (.tool-versions) pins were found.
  • node_modules was excluded from the Dockerfile scan.
  • Nothing has been changed. This issue is a report only.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    securitySecurity-related concerntech-debtTechnical debt to address

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions