Skip to content

Zero-install dev/start on Bun via native auto-install (carve from #669) #675

Description

@vivek7405

Problem

Bun resolves bare npm specifiers on the fly when no node_modules is present (auto-install, the Bun analog of Deno 2's npm: resolution but with no prefix). Verified on Bun 1.3.14: bun --bun running a script that does import { html } from '@webjsdev/core' (and a second importing drizzle-orm) auto-installs both from npm and runs, with no node_modules. Built-in SQLite (#670) needs no install. So webjs's pure-JS packages are auto-install-compatible, and a zero-install dev/start on Bun should be reachable.

It does NOT work end to end today because the CLI runs the SERVER on Node, so the app's imports hit Node resolution (which has no auto-install) and fail. Reproduced: bunx @webjsdev/cli@latest start on a no-node_modules app booted the server, but the page render threw ERR_MODULE_NOT_FOUND: @webjsdev/core with a node:internal/modules/esm stack. The CLI spawned the server child via spawn(process.execPath, ...) (the hot-reload supervisor), which is Node. The scaffold's bun --bun webjs start does force Bun, but relies on the webjs bin already being in node_modules/.bin, so it is not zero-install either.

This is the Bun half of #669, carved out because it is reachable with a small launcher change rather than the full resolve-hook (Node still needs that hook, so it stays in #669).

Design / approach

When invoked under Bun (process.versions.bun set), run the SERVER genuinely on Bun so the app's imports (and @webjsdev/*) flow through Bun auto-install, instead of spawning a Node child via process.execPath. The hot-reload supervisor already branches node --watch vs bun --hot (#514), so the seam exists; the gap is the zero-install bootstrap (bunx @webjsdev/cli ... must end up running the server on Bun, not Node, and must not require the webjs bin to pre-exist in node_modules).

Scope to BUN ONLY. Node has no native auto-install (only npx for bin tools and experimental URL-only network imports), so #669's module.register resolve-hook remains the Node mechanism and stays in #669. jspm/client behavior is unchanged (owner constraint).

Implementation notes (for the implementing agent)

  • Where to edit: packages/cli/bin/webjs.js (the launch path, the hot-reload supervisor that spawns process.execPath around L156-176, and the dev/start command handling). The scaffold scripts in packages/cli/lib/create.js (~L331-332, bun --bun webjs dev / bun --bun webjs start) may also need a zero-install variant or doc.
  • The fix is making the server RUN on Bun under a bunx @webjsdev/cli invocation: re-exec / run in-process under Bun rather than spawning Node. Confirm the in-process (--no-hot) path already runs on the current runtime (it should), and that the supervised (bun --hot) path keeps the child on Bun.
  • Landmines: keep the Node path EXACTLY as-is (Bun-only change). The .server.{js,ts} boundary + the import-graph auth gate must stay intact (zero-install must not change what is servable). Auto-installed deps live in Bun's global cache, NOT node_modules, so anything that reads node_modules for versions degrades: locatePackageDir (packages/server/src/dev.js ~L2436) and getPackageVersion (packages/server/src/vendor.js ~L253) already return null gracefully on a miss, so the importmap falls back to a latest jspm pin rather than crashing. That is the Zero-install dev: no install command, transparent resolution (Node+Bun) #669 reproducibility tradeoff (the anchor shifts from a per-app lockfile to bun.lock plus the pin file); document it.
  • Prove on a REAL scaffolded app that pins published @webjsdev/*, NOT the monorepo workspace (the workspace resolves @webjsdev/* to local packages and bypasses auto-install, so it cannot test this).
  • Invariants: no-build model (Support both Bun and Node runtimes (first-class create + run) #508); the server-only boundary + auth gate; runtime parity (the Node path is untouched).

Acceptance criteria

  • A freshly scaffolded app with NO node_modules, served via bunx @webjsdev/cli dev and start on Bun, renders its pages (the @webjsdev/core import resolves via auto-install, no ERR_MODULE_NOT_FOUND).
  • webjs db migrate works under auto-install on Bun (drizzle-kit auto-installs; confirm the migrate run path).
  • The client importmap / jspm path still works without node_modules (falls back to a latest pin gracefully); jspm behavior is otherwise unchanged.
  • The Node path is unchanged (no regression to webjs dev / start on Node).
  • A test proves a no-node_modules app serves on Bun (a test/bun or scaffold test that removes node_modules then boots), with a counterfactual where applicable.
  • Docs updated (a "zero-install on Bun" note in the deployment / getting-started docs-site pages + the scaffold Bun docs + agent-docs), including the reproducibility tradeoff.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

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