Skip to content

fix: fall back to node when bun and tsx are not installed#3130

Open
jlaustill wants to merge 4 commits into
tscircuit:mainfrom
jlaustill:fix/node-compat-runner-and-meta-dir
Open

fix: fall back to node when bun and tsx are not installed#3130
jlaustill wants to merge 4 commits into
tscircuit:mainfrom
jlaustill:fix/node-compat-runner-and-meta-dir

Conversation

@jlaustill
Copy link
Copy Markdown

Problem

Three separate issues cause tsci dev (and build/snapshot) to fail hard on Node-only systems:

1. cli/entrypoint.js — no fallback beyond tsx

const runner = commandExists("bun") ? "bun" : "tsx"

If neither bun nor tsx is installed the spawned process fails. tsx isn't a guaranteed dependency on every dev machine, and it shouldn't be a hard requirement just to run compiled JS.

2 & 3. cli/build/worker-pool.ts and cli/snapshot/worker-pool.tsimport.meta.dir is Bun-only

path.join(import.meta.dir, "build.worker.ts")

import.meta.dir is a Bun extension; it is undefined in Node, causing path.join to throw once the worker entrypoint path is resolved.

Fix

entrypoint.js: chain a final process.execPath fallback so the current Node binary is always available:

const runner = commandExists("bun") ? "bun" : commandExists("tsx") ? "tsx" : process.execPath

worker-pool.ts (both): add a one-time cross-runtime __metaDir shim at the top of each file, then replace all import.meta.dir usages:

const __metaDir: string =
  (import.meta as unknown as { dir?: string }).dir ?? // Bun
  import.meta.dirname ??                              // Node >=21.2
  dirname(fileURLToPath(import.meta.url))             // Node <21.2

Tested

Verified tsci dev starts and serves the preview on a system with Node 24 and no Bun installed.

🤖 Generated with Claude Code

jlaustill and others added 4 commits May 28, 2026 16:50
Three related changes to make the CLI work in Node-only environments:

1. entrypoint.js: runner selection was `bun || tsx` with no further
   fallback. Any system without both bun and tsx would fail at spawn.
   Now: `bun || tsx || process.execPath` (the current node binary).

2. cli/build/worker-pool.ts: import.meta.dir is a Bun-only property.
   Replace with a cross-runtime shim that prefers import.meta.dir (Bun),
   then import.meta.dirname (Node >=21.2), then dirname(fileURLToPath(…)).

3. cli/snapshot/worker-pool.ts: same import.meta.dir fix as above.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- worker-pool.ts (build + snapshot): fix broken __metaDirname reference
  caused by replace_all matching import.meta.dir inside import.meta.dirname;
  use proper ImportMetaWithDir cast covering both .dir (Bun) and .dirname
  (Node >=21.2); move all imports above the shim const; run biome format

- entrypoint.js: apply biome format (semicolons + indentation)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The previous commit applied biome from a mismatched npm-installed version,
producing tabs + semicolons. Restore both worker-pool files from upstream
and apply only the minimal patch needed: add dirname/fileURLToPath imports
and the __metaDir shim in the original project style (2-space indent, no
semicolons), then replace all import.meta.dir usages with __metaDir.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ners)

entrypoint.js: restore from upstream and apply only the runner change in
the original style — 2-space indent, no semicolons, ternary broken to
match biome 1.9.3 line-length rules.

snapshot/worker-pool.ts: consolidate the jsBundledPath.join() call to one
line — __metaDir is shorter than import.meta.dir so the line now fits
within 80 chars and biome collapses it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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