Skip to content

refactor(repo): drop tsx, rely on native Node type stripping#1620

Merged
ssalbdivad merged 3 commits into
arktypeio:mainfrom
gabroberge:ci/node-26-node-options
Jun 30, 2026
Merged

refactor(repo): drop tsx, rely on native Node type stripping#1620
ssalbdivad merged 3 commits into
arktypeio:mainfrom
gabroberge:ci/node-26-node-options

Conversation

@gabroberge

@gabroberge gabroberge commented May 17, 2026

Copy link
Copy Markdown
Contributor

Summary

From Node 26 onward, --experimental-transform-types is not allowed in NODE_OPTIONS, so any node child process started after addNodeDevOptions() fails. This originally surfaced as a failing compatibility (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 erasable declare/type-level forms — the enum in ark/regex/state.ts lives inside a declare 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, no tsx).
  • 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 is private, and the published arktype package declares no engines, so library consumers are unaffected.
  • Dropped tsx entirely — no test context needs it:
    • removed import=tsx from all three synced mocha configs (package.json, ark/repo/mocha.package.jsonc, .vscode/settings.json)
    • ark/fast-check test and the @ark/attest self-test spawn now run via plain node
    • removed the tsx devDependency
  • ark/type/__tests__/realWorld.test.ts: de-sugared the one parameter property so the entire codebase is strip-compatible.

Test plan

  • testTyped1703 passing under native stripping, no tsx
  • @ark/fast-check integration — 56 passing via node ../repo/testPackage.ts
  • @ark/attest snapPopulation / self-tests — 63 passing (exercises the native node template spawn)
  • nodeDevOptions emits only --conditions ark-ts; prettier + eslint clean
  • full Node matrix (lts / lts-1 / latest) via CI

Notes

  • engine-strict was intentionally not enabled — it risks failing installs on transitive-dependency engine mismatches; the engines bump alone documents the requirement (pnpm warns by default). Easy to add later if desired.
  • The Node versions CI tests (lts/*, lts/-1, latest) all strip by default, so the previous version-ladder branches were never exercised in CI anyway.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 Node 26+ takes the tsx fallback path.
  • Extract versionedFlagsFor(major, minor) — flag selection moves out of the top-level ternary into a named function, with a sibling getFallbackReason(major) that emits distinct copy for the 26+ case vs the pre-22.7 case.

Summary | 1 file | 1 commit | base: mainci/node-26-node-options


Node 26 removes --experimental-transform-types

Before: addNodeDevOptions() injected --experimental-transform-types --no-warnings into NODE_OPTIONS for any major > 22, so child node processes on Node 26+ aborted with --experimental-transform-types is not allowed in NODE_OPTIONS.
After: Node 26+ logs a fallback reason and uses --import tsx instead, matching the pre-22.7 fallback 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.

ark/repo/nodeOptions.js

Pullfrog  | View workflow run | Using 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>
@ssalbdivad ssalbdivad changed the title fix(repo): use tsx fallback on Node 26+ for NODE_OPTIONS fix(repo): rely on native type stripping for NODE_OPTIONS on Node 26+ Jun 23, 2026
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>
@ssalbdivad ssalbdivad changed the title fix(repo): rely on native type stripping for NODE_OPTIONS on Node 26+ refactor(repo): drop tsx, rely on native Node type stripping Jun 23, 2026
@ssalbdivad ssalbdivad merged commit d0c43a9 into arktypeio:main Jun 30, 2026
6 checks passed
@github-project-automation github-project-automation Bot moved this from To do to Done (merged or closed) in arktypeio Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done (merged or closed)

Development

Successfully merging this pull request may close these issues.

2 participants