install: do not auto-install a transitive peer dependency on bun
Closed
RO
1mo ago+239+239+012345678901234567890123456789-2-2-0123456789
Problem
bun add bun-plugin-tailwindinstalls the npmbunpackage into node_modules: ~80MB of binaries on linux, ~170MB on Windows (#39755).bun why bunshows it comes frompeer bun-plugin-tailwind@0.1.2 (requires >=1.0.0).- Bun auto-installs non-optional peer dependencies, npm does the same with this package. The plugin declares a hard peer dep on
bun, and nothing tells the installer that the running runtime already satisfies it.
Fix
- Treat a remote package's peer dependency named
bunas an optional peer. Both parse paths change insrc/install/lockfile/Package.rs: the registry manifest path (from_npm) and the generic package.json path, gated on!is_main && !is_workspace. - An optional peer is never auto-installed, but the existing hoister still binds it when the
bunpackage is present through a real dependency edge. - A direct dependency on
bunin the user's package.json (any kind, including a root peer dependency) still installs it. - Verified:
test/cli/install/bun-install-registry.test.ts(newpeer dependency on bunblock, stock bun fails the first test). Also ranbun-lock.test.ts,isolated-install.test.ts,bun-update-transitive.test.ts, and the full registry suite.
Background
- The installer records each dependency edge with
Behaviorflags.PEER | OPTIONALmeans: bind to the package if something else installs it, otherwise leave the edge unresolved.--omit=peerandpeerDependenciesMeta: { optional: true }already use this path, so lockfile round-trips and hoisting are covered by existing machinery. - Remote packages (registry, git, tarball, folder) parse with
Featureswhereis_mainandis_workspaceare false. The root and workspace package.json files parse withis_mainoris_workspaceset, so their ownbundependencies keep the old behavior. - New registry fixtures:
bun@1.0.0/1.1.0andpeer-on-bun@1.0.0(generator scriptcreate-bun-peer-packages.ts).
Notes
- An existing bun.lock that already pins the
bunpeer keeps its resolution on reload: lockfile loads do not reparse manifests, so nothing is removed behind the user's back. A fresh resolve (no lockfile, orbun update) drops it. - If
bunappears in bothdependenciesandpeerDependenciesof the same remote package, the duplicate-promotion loop infrom_npmkeeps the regular dependency, so it still installs. - The version range of the peer is not checked against the runtime version. The copy in node_modules never changes which runtime executes, so installing a newer
bunpackage would not help anyway. - The saved bun.lock lists
bununderoptionalPeersfor such packages, which keeps reinstalls from a saved lockfile stable (asserted in the test). - The 14 failures in
bun-install.test.tslocally are network tests (bitbucket, gitlab, public tarball URLs) that cannot run in the sandbox, unchanged by this diff.
no test proof · iteration 0 · Platform-specific test(s) that do not run on this machine. Deferring to CI, which covers all platforms: test/cli/install/bun-install-registry.test.ts