Skip to content

fix: bun zero-install breaks every spawned-subprocess command (db/test/seed/typecheck); pin at the spawn layer #695

Description

@vivek7405

Problem

A fresh Bun zero-install scaffold cannot set up its database. Reproduced cleanly (fresh bun pm cache rm, shipped cli@0.10.25):

npm create webjs@latest fs -- --runtime bun   # skips install (#691)
cd fs && bun run db:generate
# SyntaxError: Export named 'defineRelations' not found in
#   .../cache/drizzle-orm@0.45.2@@@1/index.js

Bun fetched drizzle-orm@0.45.2 and drizzle-kit@0.31.10 (both the wrong 0.x major), despite the package.json pinning 1.0.0-rc.3. All three templates use Drizzle, so this breaks db setup for every bun zero-install app. The npm/node path works (npm honors the exact pin).

Root cause (see #690 for the full cross-version research)

  1. Bun RUNTIME auto-install ignores the package.json version for a bare import. An empty cache resolves to the absolute latest major. Verified across Bun 1.0.0 through 1.4.0-canary. Only an inline EXACT specifier (drizzle-orm@1.0.0-rc.3) is honored; inline ranges and tags ENOENT.
  2. feat: pin Bun zero-install deps via an onLoad specifier-rewrite from package.json #685 compensates by rewriting a bare import to inline-exact, but the Bun.plugin runs ONLY in the webjs server process.
  3. webjs db <generate|migrate|push|studio> (packages/cli/bin/webjs.js, case 'db') resolves the drizzle-kit bin (resolveBin(cwd, 'drizzle-kit')) and SPAWNS it as a separate bun drizzle-kit subprocess. That subprocess has no feat: pin Bun zero-install deps via an onLoad specifier-rewrite from package.json #685 plugin, so its bare import 'drizzle-orm' (from the schema) hits raw auto-install against an empty cache and gets the wrong major.

The trigger is #691 (skip-install default for bun). Before it, bun create ran bun install, which DOES honor pins, so the db worked. The cli AGENTS.md still says "since webjs create auto-installs", now stale for bun.

Design / approach

Recommended: A. do not default to skip-install for db templates (revert the #691 default, at least when Drizzle is present, which is all three templates). Bun zero-install fundamentally cannot pin a spawned tool's deps, so the skip-install default is unsafe for any app with db tooling. The npm path is unaffected.

Alternatives considered:

  • B. Spawn the db tool as bun --preload <pin-registrar> drizzle-kit ... so the feat: pin Bun zero-install deps via an onLoad specifier-rewrite from package.json #685 plugin loads in that process. Incomplete on its own: resolveBin still resolves the WRONG drizzle-kit bin (0.31.10) under an empty cache, which --preload does not fix.
  • C. webjs db runs a targeted bun install when node_modules is absent on bun. Works, but it is a per-command install that surprises the user mid-command.

Implementation notes (for the implementing agent)

Acceptance criteria

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions