feat: transitive bun dependencies via JAR manifests#6
Merged
Conversation
When a Scala.js library publishes with BunScalaJSModule, it can embed a bun dependency manifest (META-INF/bun/bun-dependencies.json) and lockfile (META-INF/bun/bun.lock) in the JAR. Consumer builds scan classpath JARs for these manifests and merge them into package.json automatically — making JS deps transitive, like Coursier does for JVM. Write side (library authors): - bunDependencyManifest: generates manifest + embeds lockfile - bunDependencyManifestResources: wire into JAR resources - bunOptionalDeps: optional JS packages (won't fail if unavailable) Read side (consumers): - classpathBunDeps/classpathBunDevDeps: scan JARs for manifests - classpathBunLockfiles: extract embedded lockfiles - transitiveNpmDeps: now includes JAR-discovered deps - bunInstall: seeds lockfile from JARs for deterministic resolution BunManifest: data class + JSON serialization + JAR I/O + merge. 11 new unit tests covering round-trip, JAR read/write, merge, edge cases. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…usion
- bun"pkg@version" compile-time validated string interpolator
validates package name format at compile time, returns plain String
- bunDeps / bunDevDeps as primary API (npmDeps delegates to bunDeps)
- bunOptionalDeps for packages that won't fail if unavailable
- Auto-resource inclusion: resources automatically includes the bun
dependency manifest when bunDeps is non-empty. Zero manual wiring.
- 8 new interpolator tests, 30 total tests passing
Library authors just declare deps:
def bunDeps = Task { Seq(bun"react@^19.0.0") }
// Manifest + lockfile auto-embedded in JAR. Consumers get them free.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- npmDeps and bunDeps are now independent (both default to Seq.empty), merged at the transitive level — eliminates circular delegation footgun - Extract manifest generation into BunPublishModule opt-in trait so existing users don't get unexpected JAR content changes Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Lockfiles are application-level artifacts, not library-level. Embedding them in JARs had fundamental issues: no merge strategy across libraries, arbitrary winner selection, and bun.lockb never actually extracted. Strip lockfile embedding from BunPublishModule, classpath lockfile scanning, and seeding logic from bunInstall. The manifest system (bun-dependencies.json) remains — it correctly handles transitive dep discovery. Project-level lockfile management will follow in a separate PR. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add classpathBunOptionalDeps + transitiveBunOptionalDeps so optional deps flow through JAR manifests like regular and dev deps - mkBunPackageJson uses transitive optional deps instead of local-only - BunPublishModule triggers manifest on any dep type (including devDeps) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
META-INF/bun/bun-dependencies.jsonmanifests embedded in published JARs — analogous to how Coursier resolves JVM deps from POMsBunPublishModuleopt-in trait for libraries that want to embed manifestsbun"pkg@version"compile-time validated string interpolator andbunDeps/bunDevDepsaliases (backward-compatible with existingnpmDeps/npmDevDeps)npmDepsandbunDepsare independent (no circular delegation) — both merged at the transitive levelDesign decisions
BunPublishModule— existingBunScalaJSModuleusers see no JAR content changes or build overhead.npmDeps/bunDepsare independent — avoids circular delegation footgun if both are overridden. Merged transparently intransitiveNpmDeps.What's next (Phase 2)
Project-level lockfile management in a follow-up PR:
bun.lockin workspace rootbunUpdateLockcommand to regeneratebunInstallseeds from committed lockfilebunFrozenLockfileenforces in CITest plan
./mill millbun.compile— compiles cleanly./mill millbun.test— all 30 unit tests pass (11 BunManifest + 8 BunDep + 7 SplitDep + 4 ExecutableCandidates)BunPublishModule🤖 Generated with Claude Code