Skip to content

feat!: upgrade execa to v10 and require Node 22 - #601

Merged
aversini merged 1 commit into
mainfrom
feat/execa-10
Jul 21, 2026
Merged

aversini merged 1 commit into
mainfrom
feat/execa-10

Conversation

@aversini

Copy link
Copy Markdown
Collaborator

Upgrades execa in @node-cli/run from 9.6.1 to 10.0.0.

Breaking changes in execa 10 that touch this package

Change Affects run?
execaCommand() / execaCommandSync() removed Yes
engines.node ^18.19.0 || >=20.5.0 → >=22 Yes
Subprocess is no longer a ChildProcess (.on(), .send() move to .nodeChildProcess) No
stdio: [..., 'ipc'] → ipc: true No
input/inputFile now take precedence over inherited stdin No

The code change

-import { execa, execaCommand } from "execa";
+import { execa } from "execa";
@@
-const { stdout, stderr } = await execaCommand(command, execaOptions);
+const { stdout, stderr } = await execa(execaOptions)`${command}`;

The non-shell branch is untouched — it already used the local parseCommandString helper that execa's migration guide points to.

The Node floor

packages/run/package.json declared a non-standard top-level "node": ">=16" field. npm and pnpm read engines.node, so that floor was never enforced. It is replaced with a real "engines": { "node": ">=22" } so execa 10's requirement is surfaced at install time rather than being silently transitive.

Node 20 reached EOL on 2026-04-30, so a Node 22 floor excludes only unsupported runtimes. CI already runs 24.x.

No downstream pin bumps needed — search, npmrc, and examples/run consume run via workspace:*.

Verification

  • pnpm test — 268 tests across 12 packages pass
  • pnpm lint clean across 13 projects; tsc + swc build clean
  • End-to-end, not just unit tests: examples/run/run-example.js output is byte-identical to execa 9, and the built search CLI exercised both run code paths (id -nu non-shell, --command "wc -l" shell)
  • Error shapes unchanged — shortMessage, exitCode, and ENOENT handling match execa 9 for every existing assertion

Follow-up (not in this PR)

The other 13 packages carry the same typo'd, non-enforced "node" field. Nothing reads it, but search and npmrc now transitively require Node 22 while declaring >=18 / >=16. Worth a separate cleanup.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WxPdHpfW5B4evcecAmHHqa

execa 10 removes execaCommand(); the shell branch now uses the
tagged-template form execa(options)`${command}`. The non-shell branch
is unchanged — it already used the local parseCommandString helper that
execa's migration guide recommends.

execa 10 also raises its engine floor to Node 22. packages/run declared
a non-standard top-level "node": ">=16" field, which npm never enforced;
it is replaced with a real engines.node ">=22" so the requirement is
actually surfaced at install time.

Verified: 268 repo tests pass, plus end-to-end runs of examples/run and
the search CLI exercising both the shell and non-shell code paths.
Error shapes (shortMessage, exitCode, ENOENT handling) are unchanged
from execa 9.

BREAKING CHANGE: @node-cli/run now requires Node.js 22 or later.
@aversini
aversini merged commit feceb6e into main Jul 21, 2026
4 checks passed
@aversini
aversini deleted the feat/execa-10 branch July 21, 2026 17:15
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