Skip to content

feat: Drop Node.js 20 support. Node.js >=22.12 is now required#1033

Open
macdonst wants to merge 8 commits intomainfrom
drop-node-20
Open

feat: Drop Node.js 20 support. Node.js >=22.12 is now required#1033
macdonst wants to merge 8 commits intomainfrom
drop-node-20

Conversation

@macdonst
Copy link
Copy Markdown

@macdonst macdonst commented Apr 30, 2026

Description

Node 20 officially exited it's maintenance mode on April 30th, 2026. This means we can finally drop support for this version of Node in the CLI. The purpose of this PR is to update the code to warn users if they are running on a node version less than 22.12, update the engines version of node in all our package.json files and drop node 20 from our testing matrix.

This PR intentionally does not remove any node packages that may not be required anymore. For example:

rimraf - sticks around in case anyone is contributing from Windows
tinyglobby - node 22 now supports fs.glob but our usage of tinyglobby includes some options that fs.glob doesn't support out of the box so more consideration is required here.
nanoid - we only use one method in from this package, customAlphabet. To me this is a top candidate to get vendored as we can copy (with attribution) approximately 50 LOC from an MIT project instead of leaving us open to a supply chain for a package that gets over 100 million downloads a week. Single maintainer.
execa - used frequently in this repo and we should probably examine if we can replace it with node:child_process and once again not leave us open to a supply chain for a package that gets over 100 million downloads a week. Single maintainer.

What to review

Should be pretty self explanatory. Did I miss any node 20 references?

Testing

All existing tests are passing. I didn't think it was necessary to add a test isSupportedNodeVersion.


Note

Medium Risk
This is a breaking runtime/packaging change: installs and executions on Node 20 will now fail due to updated engines and CLI startup version checks. CI and E2E coverage also shift to Node 22/24 only, which may hide issues specific to older runtimes.

Overview
Drops Node.js 20 support across the monorepo by bumping all affected package.json engines.node constraints to >=22.12 and updating the CLI entrypoint (bin/run.js) to hard-error unless running on Node >=22.12.

Updates GitHub Actions workflows to remove Node 20 from test/e2e matrices, move coverage collection/artifact upload to Node 22, and set release/preview workflows to run on Node 22. Removes Node-version-specific E2E test skips that were only needed for Node 20/yarn v1, and adds a changeset marking the CLI packages for a minor bump.

Reviewed by Cursor Bugbot for commit eb39577. Bugbot is set up for automated code reviews on this repo. Configure here.

@macdonst macdonst requested a review from a team as a code owner April 30, 2026 16:02
@macdonst macdonst requested review from mttdnt and removed request for a team April 30, 2026 16:02
@claude
Copy link
Copy Markdown

claude Bot commented Apr 30, 2026

Claude finished @macdonst's task in 1m 10s —— View job


Review

  • Read diff and changed files
  • Review changeset
  • Check bin/run.js version check logic
  • Review CI workflow changes
  • Post findings

1. Changeset bump type should be major, not minor

File: .changeset/pr-1033.md

Dropping Node 20 support is a semver-breaking change — users running Node <22.12 will get a hard error. This warrants a major bump for all affected packages, not minor.

Fix this →

2. Changeset summary reads as a commit message, not a user-facing description

File: .changeset/pr-1033.md, line 9

feat: drop node 20 is a commit message format, not a user-facing changelog entry. It should describe the effect on developers using the package. Suggested: Node.js 20 is no longer supported; Node.js 22.12 or later is required.

Fix this →

3. No tests for isSupportedNodeVersion

File: packages/@sanity/cli/bin/run.js, lines 10–14

The PR description notes this was intentionally skipped. However, this function gates CLI startup and has non-trivial boundaries (e.g., 22.11 should fail, 22.12 should pass, 23.x should pass). A small unit test would protect against regressions when the minimum is bumped again.


@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

📦 Bundle Stats — @sanity/cli

Compared against main (26102ba7)

@sanity/cli

Metric Value vs main (26102ba)
Internal (raw) 2.1 KB -
Internal (gzip) 799 B -
Bundled (raw) 11.04 MB -
Bundled (gzip) 2.07 MB -
Import time 856ms +34ms, +4.1%

bin:sanity

Metric Value vs main (26102ba)
Internal (raw) 734 B -241 B, -24.7%
Internal (gzip) 397 B -63 B, -13.7%
Bundled (raw) 9.84 MB -242 B, -0.0%
Bundled (gzip) 1.77 MB -70 B, -0.0%
Import time 1.96s +10ms, +0.5%

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — @sanity/cli-core

Compared against main (26102ba7)

Metric Value vs main (26102ba)
Internal (raw) 93.1 KB -
Internal (gzip) 21.9 KB -
Bundled (raw) 21.62 MB -
Bundled (gzip) 3.42 MB -
Import time 783ms +2ms, +0.3%

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

📦 Bundle Stats — create-sanity

Compared against main (26102ba7)

Metric Value vs main (26102ba)
Internal (raw) 976 B -
Internal (gzip) 507 B -
Bundled (raw) 50.7 KB -
Bundled (gzip) 12.6 KB -
Import time ❌ ChildProcess denied: node -
Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 30, 2026

Coverage Delta

File Statements
packages/@sanity/cli/src/services/documents.ts 100.0% (±0%)

Comparing 1 changed file against main @ 26102ba71f4727a17e480b4224cc8c855b41fcbb

Overall Coverage

Metric Coverage
Statements 84.2% (±0%)
Branches 74.1% (±0%)
Functions 84.0% (±0%)
Lines 84.6% (±0%)

macdonst and others added 4 commits April 30, 2026 14:39
Signed-off-by: Simon MacDonald <simon.macdonald@gmail.com>
Signed-off-by: Simon MacDonald <simon.macdonald@gmail.com>
Signed-off-by: Simon MacDonald <simon.macdonald@gmail.com>
@socket-security
Copy link
Copy Markdown

socket-security Bot commented Apr 30, 2026

macdonst and others added 2 commits April 30, 2026 14:57
@macdonst macdonst changed the title feat: drop node 20 BREAKING CHANGE: Drop Node.js 20 support. Node.js >=22.12 is now required Apr 30, 2026
@macdonst macdonst changed the title BREAKING CHANGE: Drop Node.js 20 support. Node.js >=22.12 is now required major: Drop Node.js 20 support. Node.js >=22.12 is now required Apr 30, 2026
@macdonst macdonst changed the title major: Drop Node.js 20 support. Node.js >=22.12 is now required feat: Drop Node.js 20 support. Node.js >=22.12 is now required Apr 30, 2026
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.

1 participant