Skip to content

feat: pin Bun zero-install deps via an onLoad specifier-rewrite from package.json #685

Description

@vivek7405

Problem

Bun zero-install (bun run dev/start via the webjs-bun.mjs bootstrap, no node_modules) runs dependencies at LATEST, ignoring package.json + bun.lock (#684 research, #683 docs). That is a breaking-major hazard and is why #682 (defaulting bun create to --no-install) was closed.

The #684 research found a working fix: Bun honors INLINE versions in a specifier (import 'zod@3.22.4'), and an onLoad transform (webjs already runs one for TS-strip on Bun) can rewrite a bare specifier to its package.json-pinned inline version, so auto-install fetches the pinned version. Verified in a sprite: an onLoad rewrite of import('zod/...') to import('zod@3.22.4/...') made a bare import resolve to 3.22.4 instead of latest (F_VERSION=3.22.4).

Design / approach

In webjs's Bun onLoad plugin, after (or as part of) the TS-strip transform, rewrite import specifiers of DECLARED dependencies (from the app's package.json, preferably the exact version from bun.lock when present) to inline-versioned specifiers: from 'zod' becomes from 'zod@3.22.4', import('zod/sub') becomes import('zod@3.22.4/sub'). Bun auto-install then fetches the pinned version. This makes zero-install run the app's pinned deps, not latest.

Only the app's DIRECT deps need rewriting; a pinned direct dep brings its own subtree from its manifest. Confirm that holds.

Implementation notes (for the implementing agent)

Acceptance criteria

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