refactor(repo): drop tsx, rely on native Node type stripping#1620
Conversation
6cf6bb1 to
58bd3d1
Compare
There was a problem hiding this comment.
No new issues found.
TL;DR — Gates --experimental-transform-types to Node 22.7 through 25.x and falls back to --import tsx on Node 26+, where the flag was removed and is rejected inside NODE_OPTIONS.
Key changes
- Cap experimental-transform-types at Node 25 — predicate is now
(major > 22 && major < 26) || (major === 22 && minor >= 7), so Node26+takes thetsxfallback path. - Extract
versionedFlagsFor(major, minor)— flag selection moves out of the top-level ternary into a named function, with a siblinggetFallbackReason(major)that emits distinct copy for the26+case vs the pre-22.7case.
Summary | 1 file | 1 commit | base: main ← ci/node-26-node-options
Node 26 removes --experimental-transform-types
Before:
addNodeDevOptions()injected--experimental-transform-types --no-warningsintoNODE_OPTIONSfor anymajor > 22, so childnodeprocesses on Node 26+ aborted with--experimental-transform-types is not allowed in NODE_OPTIONS.
After: Node 26+ logs a fallback reason and uses--import tsxinstead, matching the pre-22.7fallback shape.
Verified against the Node v26.1.0 TypeScript docs: the v26.0.0 history entry reads "Removed --experimental-transform-types flag." Type stripping itself remains on by default in 26, but the transform flag is gone — passing it via NODE_OPTIONS is what triggers the error this PR avoids. The single consumer is ark/repo/ts.js, which calls addNodeDevOptions() before spawning a node child via execSync, so the fix lands exactly where it needs to.
Claude Opus | 𝕏
…ansform-types Node >= 26 rejects `--experimental-transform-types` in NODE_OPTIONS. Since this repo contains no syntax that requires type *transformation* (only erasable `declare`/type-level forms — the regex `enum` is inside a `declare namespace`), native type *stripping* is sufficient: - pass no flag where Node strips by default (>= 22.18 / 23.6 / 24+, incl. 26) - use `--experimental-strip-types` on the flagged range (22.6–23.5) - fall back to tsx below 22.6 Also de-sugar the one parameter property in realWorld.test.ts so the entire codebase is strip-compatible. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Every Node version we support strips TypeScript types by default (engines floor bumped 18 -> 22.18.0, where unflagged stripping landed in the 22.x line; also 23.6+/24+). The codebase has no transform-only syntax, so no loader or flag is needed anywhere: - nodeOptions.js: collapse the version ladder; pass only --conditions ark-ts - remove `import=tsx` from all three synced mocha configs (root package.json, ark/repo/mocha.package.jsonc, .vscode/settings.json) - fast-check test + attest self-test spawn run via plain `node` - drop the `tsx` devDependency Verified tsx-free under native stripping: testTyped (1703 passing), fast-check integration (56), attest snapPopulation/self-tests (63). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

Summary
From Node 26 onward,
--experimental-transform-typesis not allowed inNODE_OPTIONS, so anynodechild process started afteraddNodeDevOptions()fails. This originally surfaced as a failingcompatibility (ubuntu-latest, latest)check.Instead of falling back to
tsx, this leans entirely on Node's native type stripping, which is the default on every version we support. The repo contains no syntax that requires type transformation (only erasabledeclare/type-level forms — theenuminark/regex/state.tslives inside adeclare namespace), so stripping alone is sufficient and no loader or flag is needed anywhere.Changes
ark/repo/nodeOptions.js: collapsed to pass only--conditions ark-ts(no--experimental-transform-types, notsx).engines.node: bumped>=18→>=22.18.0(unflagged stripping landed in the 22.x line at 22.18.0; also 23.6+/24+). Dev-only — the root package isprivate, and the publishedarktypepackage declares noengines, so library consumers are unaffected.tsxentirely — no test context needs it:import=tsxfrom all three synced mocha configs (package.json,ark/repo/mocha.package.jsonc,.vscode/settings.json)ark/fast-checktest and the@ark/attestself-test spawn now run via plainnodetsxdevDependencyark/type/__tests__/realWorld.test.ts: de-sugared the one parameter property so the entire codebase is strip-compatible.Test plan
testTyped— 1703 passing under native stripping, no tsx@ark/fast-checkintegration — 56 passing vianode ../repo/testPackage.ts@ark/attestsnapPopulation / self-tests — 63 passing (exercises the nativenodetemplate spawn)nodeDevOptionsemits only--conditions ark-ts; prettier + eslint cleanNotes
engine-strictwas intentionally not enabled — it risks failing installs on transitive-dependency engine mismatches; theenginesbump alone documents the requirement (pnpm warns by default). Easy to add later if desired.lts/*,lts/-1,latest) all strip by default, so the previous version-ladder branches were never exercised in CI anyway.