Monorepo
pubm treats monorepos as a core use case. It discovers packages, understands dependency order, and can release JavaScript, Rust, and Deno workspaces from the same repository.
What pubm detects automatically
Section titled “What pubm detects automatically”Workspace discovery currently looks for:
pnpm-workspace.yamlCargo.tomlwith[workspace]deno.jsonordeno.jsoncwithworkspacepackage.jsonwith aworkspacesfieldbunfig.tomltogether withpackage.jsonworkspaces to classify Bun workspaces
After discovery, pubm builds a dependency graph and uses it to determine publish order.
When to rely on discovery vs. explicit package config
Section titled “When to rely on discovery vs. explicit package config”Automatic discovery works well when:
- every workspace package is publishable
- you do not need to mix ecosystems with selective publish targets
Use explicit packages config when:
- only some workspace packages should publish
- Rust crates live alongside JS packages
- you want to override inferred registries or add private registries
- you want the docs and release pipeline to stay explicit
Registries are inferred from each package’s manifest files. You only need registries entries in packages when the inferred set is wrong or when private registries are needed.
Publish order
Section titled “Publish order”For dependent packages, pubm publishes in topological order.
This matters because:
- npm and jsr consumers can install the new dependency version immediately
- crates.io publishing must respect crate dependency ordering
- partially ordered publishes are easier to roll back and diagnose
If a circular dependency prevents a safe publish order, pubm fails instead of guessing.
Versioning modes
Section titled “Versioning modes”independent
Section titled “independent”export default defineConfig({ versioning: "independent",});- each package can receive a different version
- each package is tagged independently
- changesets affect only the packages they mention unless groups change that result
export default defineConfig({ versioning: "fixed",});- packages released together share one version
- the repository gets one release tag such as
v1.8.0
Fixed and linked groups
Section titled “Fixed and linked groups”export default defineConfig({ versioning: "independent", fixed: [["@acme/core", "@acme/react", "@acme/vue"]], linked: [["@acme/cli", "@acme/config"]],});Typical release flow in a monorepo
Section titled “Typical release flow in a monorepo”pubm init --changesetspubm changesets addpubmIn a monorepo, the important difference is not the command shape but the release plan that pubm calculates from pending changesets, package groups, and dependency order.
Changesets in a monorepo
Section titled “Changesets in a monorepo”The most important rule is simple: put packages in the changeset file, not in commit messages or PR titles.
pubm changesets add will:
- discover available packages
- let you choose one or more packages
- prompt for the bump type for each selected package
- record the release summary
The standard pubm release pipeline then consumes those pending changesets during versioning.
Multi-registry monorepos
Section titled “Multi-registry monorepos”Each package’s registries are inferred from its manifest files. A package with both package.json and jsr.json resolves to both npm and jsr. A deno.json or deno.jsonc also resolves to jsr. A Cargo.toml resolves to crates. Use registries only to override or extend.
Git tags in monorepos
Section titled “Git tags in monorepos”Tag format depends on the resulting version plan.
Fixed mode
Section titled “Fixed mode”v1.4.0Independent mode
Section titled “Independent mode”@acme/core@1.4.0@acme/react@1.2.0Excluding packages from git tags
Section titled “Excluding packages from git tags”In independent mode, every package normally receives its own git tag and GitHub Release draft. Use excludeRelease to opt specific packages out of that behavior while still versioning and publishing them.
export default defineConfig({ versioning: "independent", excludeRelease: ["packages/cli/platforms/*"], packages: [ { path: "packages/core" }, { path: "packages/cli" }, { path: "packages/cli/platforms/*" }, ],});Packages matched by excludeRelease are still bumped and published to their registries. They are only skipped for git tag creation and GitHub Release drafts.
Next steps
Section titled “Next steps”- Read the Changesets guide to understand how version decisions are recorded.
- Read the Configuration guide for package-level config and grouping options.