Skip to content

chore: require Node >= 22 and pin @types/node to the lowest supported major - #976

Merged
rasmusbe merged 4 commits into
mainfrom
claude/node-types-min-version-w9tkk0
Oct 28, 2026
Merged

rasmusbe merged 4 commits into
mainfrom
claude/node-types-min-version-w9tkk0

Conversation

@rasmusbe

@rasmusbe rasmusbe commented Oct 28, 2026 •

Copy link
Copy Markdown
Member

Summary

Node 18 and 20 are end-of-life. This raises the minimum supported Node version to 22 and keeps @types/node on the same major, so TypeScript rejects Node APIs that don't exist in the oldest version we support.

  • engines.node: ^18.18.0 || >=20.0.0 → >=22.0.0
  • @types/node: ^25.9.9 → ^22.20.5 (lockfile regenerated with npm install)
  • .github/renovate.json: new rule allowedVersions: "<23" for @types/node, so Renovate only proposes minor/patch updates inside 22
  • nodejs.yml: add 22 to the test matrix alongside lts/* and latest, so CI covers the minimum version
  • publish.yml: build and publish on Node 26
  • tsconfig.json:
    • extends @tsconfig/node22 and drops the options the base already sets (strict, module, esModuleInterop, skipLibCheck)
    • types, target and lib stay overridden. With "types": [], using a Node API in src by mistake is a build error, because the library also runs in browsers and via JSR. Target/lib are handled in chore: lint for browser compatibility and modernise string handling #977.
    • the unused experimentalDecorators / emitDecoratorMetadata options are removed
  • pinefile.ts: replace rimraf with fs.rmSync, and drop the rimraf dev dependency

Dropping Node 18/20 is a breaking change, so the next release should be a major. The version in package.json is unchanged here.

Supersedes #975: its workflow bump is included here, and the new Renovate rule blocks its @types/node 26 bump.

Test plan

  • npm run lint
  • npm run build, with dist/ byte-identical before and after the @tsconfig/node22 change
  • npm test against src, dist/cjs and dist/esm (33/33 each) on Node 22.22
  • Confirmed that adding a Buffer reference in src/ now fails tsc

🤖 Generated with Claude Code

https://claude.ai/code/session_01DHTz72KwNga2DxvYdbcNUR

… major

Node 18 and 20 are end-of-life. Raise engines.node to >=22.0.0 and keep
@types/node on ^22 so TypeScript does not accept Node APIs that are
missing in the oldest supported version. Renovate is limited to <23 for
@types/node, and CI now also runs on Node 22.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DHTz72KwNga2DxvYdbcNUR
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DHTz72KwNga2DxvYdbcNUR
The library has no Node API usage and also runs in browsers and via
JSR, so compile it with "types": [] to make any accidental Node API use
a build error. Remove the unused decorator options.

Replace rimraf with fs.rmSync in the build script.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DHTz72KwNga2DxvYdbcNUR
Use the shared Node 22 base from tsconfig/bases and drop the options it
already sets (strict, module, esModuleInterop, skipLibCheck). types,
target and lib stay overridden: the library is also used in browsers
and must not see Node types. The resolved config and the emitted
declarations are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DHTz72KwNga2DxvYdbcNUR
@rasmusbe
rasmusbe merged commit e5ff78a into main Oct 28, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants