feat: require Node.js >=22.21.0 and drop EOL Node.js 20#6090
Conversation
Node.js 20 is end-of-life, so raise the minimum supported Node.js across all packages. The exact requirement is `>=22.21.0 <23 || >=24.5.0`: @arcjet/transport's proxy support relies on the built-in proxy support of the Node.js HTTP agent, which is only available on Node.js >=22.21.0 and, on the 24 line, >=24.5.0. Node.js 23 is not supported. Anyone tracking an active LTS release is unaffected. Because every package depends, directly or transitively, on @arcjet/transport, the same requirement is applied to all of them rather than only those that import it directly. (Pulling the range in now avoids changing the engines again in the upcoming proxy-support change.) Also in this change: - test matrices now run Node.js 22, 24 and 26 (dropping 20) - @types/node is pinned to the 22.x line so type checking reflects the minimum supported runtime, and renovate keeps it on that line - coverage thresholds are enabled now that the required flags are available on the supported Node.js versions Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- @arcjet/guard README runtime table and CONTRIBUTING note the new minimum with a footnote explaining the `>=22.21.0 <23 || >=24.5.0` range and why proxy support drives it - @arcjet/transport README documents the requirement and reason at its source - example READMEs: drop the obsolete `--env-file` / Node version caveat now that every supported Node.js release includes `--env-file` - examples/remix-express engines move to >=22.0.0 - @arcjet/guard runtime-detection comment links to the v22 process docs Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Arcjet Review — 🔴 High Risk
Decision: Reviewers Assigned
Rationale: This PR changes the supported Node.js runtime range across many published packages, updates CI runtime matrices, and changes pinned @types/node versions. That is broad-impact release and CI behavior, and it fires multiple escalation triggers. No direct security vulnerabilities, secrets, auth changes, injection risks, or cryptographic concerns were identified in the diff. Human review is required; no specific escalation reviewers are configured.
Summary of Changes
Raises the minimum supported Node.js version from Node 20/22.18 to >=22.21.0 <23 || >=24.5.0 across packages, updates CI from Node 20/25 to 22/26, pins @types/node to the Node 22 line, adjusts coverage scripts, and updates related documentation.
Escalation Triggers
- Dependency Changes: Multiple package.json files changed engines.node and several devDependency pins for @types/node.
- CI/CD Pipeline: GitHub Actions workflow files under .github/workflows were modified to change Node.js versions used in CI.
Review Focus Areas
- Should this example use the same engine constraint as the rest of the repository,
>=22.21.0 <23 || >=24.5.0, instead of>=22.0.0?
The PR rationale says transport proxy support requires Node >=22.21.0 or >=24.5.0. Allowing Node 22.0.0 here may advertise an unsupported runtime and create confusing install/runtime failures. - Confirm that dropping Node 20 and excluding Node 23/early Node 24 is intended as a breaking support-policy change and is reflected in release notes/versioning.
This affects all package consumers and may require a major version or explicit migration guidance depending on the project’s compatibility policy. - Verify that
actions/setup-nodecan resolve Node 26 in all CI environments and that Node 26 is intentionally supported/tested.
If the requested Node version is unavailable or not yet supported by the action cache/manifest, CI jobs will fail. - Check whether the repository lockfile should be updated alongside the package.json changes to @types/node and engines.
With npm workspaces,npm cican fail when package.json dependency pins differ from the lockfile. The diff does not show a lockfile update. - Confirm Renovate’s Node grouping and the separate @types/node rule produce the intended future updates.
The new rules allow Node updates below 27 while pinning @types/node below 23; reviewers should ensure this will not accidentally prevent needed type/security updates or create noisy PRs.
Notes
Security checklist applied: no auth/authorization, input handling, injection, secrets, or cryptography changes were identified. Dependency audit found no new third-party packages, but the @types/node pin changes and missing visible lockfile update should be verified by humans.
Path filtering: 3 files excluded by ignore paths. 48 of 51 files included in review.
Review: 4367e755 | Model: openai/gpt-5.5 | Powered by Arcjet Review
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
arcjet-rei
left a comment
There was a problem hiding this comment.
This makes more sense than bundling an unrelated semver-minor change into the proxy support, and it sets us up for 26 to go LTS in the fall. Nice! After this merges, I'll update #6089 once this merges to main.
`@arcjet/transport` passes the `proxyEnv` option to Node's HTTP agent, whose type only exists in `@types/node` 24.x. The proxy packages therefore pin 24.x rather than the 22.x line that #6090 standardized on for the rest of the monorepo (the rebase onto main reverted transport to 22.x, which fails to type-check). Refresh the lockfile to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…22.x #6090 standardized the monorepo on `@types/node` 22.x (to type-check against the minimum supported Node). The Node proxy path passes `proxyEnv` to the HTTP agent, an option only declared in `@types/node` 24.x — and transport's source is re-type-checked by every package that bundles it (e.g. @arcjet/sveltekit, @arcjet/next), so pinning the proxy packages to 24.x both diverges from the standard and breaks those consumers' builds under 22.x. Instead, keep `@types/node` at 22.x everywhere and add `proxyEnv` through an intersection type (`AgentOptions & { proxyEnv: ... }`) so it type-checks on both lines. Misspelled keys are still caught via the precise key type. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Drops support for the now end-of-life Node.js 20 and raises the minimum supported Node.js to
>=22.21.0 <23 || >=24.5.0across all packages. This lands ahead of the proxy-support change (#6089) and deliberately pulls in the exact engine range that work requires, so the engines don't have to change twice.The exact range is driven by
@arcjet/transport: its proxy support relies on the built-in proxy support of the Node.js HTTP agent, which is only available on Node.js>=22.21.0and, on the 24 line,>=24.5.0. Node.js 23 is not supported. Because every package depends (directly or transitively) on@arcjet/transport, the requirement is applied to all of them rather than only those that import it directly. Anyone tracking an active LTS release is unaffected.This is intentionally just the Node-version policy slice — no proxy/transport implementation (that's #6089).
Changes
>=22.21.0 <23 || >=24.5.0on every workspace package (incl.@arcjet/guard). Markedfeat:so release-please surfaces the new requirement in the SDK release notes.@types/nodepinned to the latest 22.x (22.19.21) so type checking reflects the minimum supported runtime; renovate keeps it on the 22.x line via a dedicated<23rule while the node/actions group tracks up to<27.--test-coverage-*flags are available on supported Node.js versions (@arcjet/ipat 100%; others ratcheted to current).@arcjet/guardREADME runtime table + footnote and CONTRIBUTING, a@arcjet/transportREADME section, the v22process.versiondoc link, example README cleanups (removed the obsolete--env-filecaveats), andexamples/remix-expressengines →>=22.0.0.The framework adapters (
@arcjet/astro,bun,deno,nuxt,remix,react-router) carry noengines/@types/nodefields, matching existing repo convention.Verification
npm run build(33 packages) ✅npm run lint(35 packages) ✅@arcjet/guard:oxlint✅,tsgotypecheck against 22.x types ✅🤖 Generated with Claude Code