Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

monochange is a cross-ecosystem release planner for monorepos.

It is easiest to learn with one safe local walkthrough before you touch provider publishing, release PRs, diagnostics, or MCP setup.

Who this guide is for

  • maintainers of monorepos that span more than one package ecosystem
  • teams replacing ad hoc release scripts with explicit change files
  • people who want a predictable release plan before adding automation

Start with one safe walkthrough

Install the prebuilt CLI from npm:

npm install -g @monochange/cli
monochange --help

Then run the core beginner flow:

Generate a starter config from the packages monochange detects:

monochange init

monochange init writes an annotated, minimal monochange.toml without default [cli.*] workflow aliases. The binary exposes immutable monochange step * commands for every built-in step when you need a direct, config-free entry point; add [cli.*] tables only for repository-specific named workflows.

For automated CI setup, include the --provider flag:

monochange init --provider github

This configures the [source] section and creates GitHub Actions workflows for changeset policy and release automation. It intentionally does not add [cli.*] workflow commands.

Validate the workspace:

monochange step validate

Discover the package ids you will use in commands and changesets:

monochange step discover --format json

Create one change file for a package id:

monochange run change --package <id> --bump patch --reason "describe the change"

Most changes should target a package id. Use group ids only when the change is intentionally owned by the whole group.

When a package is only changing because another dependency or version group moved first, author that context explicitly instead of relying on anonymous propagation:

monochange run change --package <dependent-id> --bump none --caused-by <upstream-id> --reason "dependency-only follow-up"

Preview the release plan safely:

monochange run release --dry-run --format json

Add --diff when you want unified file previews for version and changelog updates without mutating the workspace:

monochange run release --dry-run --diff

This first run is safe: nothing is published. Stop here until you are ready to prepare release files locally.

When you are ready to prepare the release locally, run monochange run release.

For human-readable local output, monochange run release --dry-run defaults to concise text. Use --format markdown for a raw Markdown artifact and --format json for automation. Add --quiet only to suppress output; combine it with --dry-run when you also need a non-mutating run. Use monochange step display-versions when you only need planned package and group versions; use monochange versions --dry-run when you want to preview internal dependency constraint updates before writing them.

This book is maintained with mdt so shared content blocks stay synchronized across pages. See the Configuration reference for how template updates work.

If you want a slower, more guided walkthrough, continue with Start here and Your first release plan.

Publishing

Recent monochange improvements made package publishing guidance and diagnostics much more actionable:

  • a dedicated trusted-publishing guide covers npm, crates.io, jsr, and pub.dev
  • CI examples prefer the official registry-maintained workflows for crates.io and pub.dev
  • a dedicated multi-package publishing guide covers monorepo tag, workflow, and package-boundary patterns
  • CLI output gives clearer manual next steps for registries that still require registry-side trusted-publishing enrollment
  • built-in publish preflight validates and reports the expected GitHub repository, workflow, and environment context for manual registries when it can infer them
  • the monochange repository wires monochange run publish-check as a dry-run PublishPackages workflow so CI can verify package-publishing readiness without publishing

Command and automation matrix

These are common commands for repositories using monochange. With the current CLI model, workflow names such as discover, change, release, and affected come from optional [cli.*] tables in monochange.toml and run as monochange run <name>; binary commands such as check, init, versions, publish, and mcp stay built in, while typed built-in operations such as validation are exposed as immutable monochange step * commands.

GoalCommandUse it when
Validate config and changesetsmonochange step validateYou changed monochange.toml or .changeset/*.md files
Inspect package ids and groupsmonochange step discover --format jsonYou need the normalized workspace model
Sync internal dependency rangesmonochange versions --dry-runYou want internal dependency references to match canonical workspace package versions
Check the next versionmonochange nextYou want the next release group and package versions from pending changesets, without writing any release state
Create release intentmonochange run change --package <id> --bump <severity> --reason "..."You need a new .changeset/*.md file
Audit pending release contextmonochange step diagnose-changesets --format jsonYou need git provenance, PR/MR links, or related issues
Preview the release planmonochange run release --dry-run --diff or monochange step prepare-release --dry-runYou want changelog/version patches without mutating the repo
Create a durable release commitmonochange step commit-releaseYou want a monochange-managed release commit with an embedded ReleaseRecord
Open or update a release requestmonochange step open-release-requestYou want a long-lived release PR/MR branch updated from current release state
Inspect a past release commitmonochange step release-record --from <ref>You need the durable release declaration from git history
Check package publish readinessmonochange publish readiness --from HEAD --output <path>You want a non-mutating preflight report before package publication
Dry-run configured publishingmonochange run publish-checkThis repository, or another repo with a similar [cli.publish-check], should exercise publishing in CI without registry mutations
Plan ready package publishingmonochange step plan-publish-rate-limits --readiness <path>You want rate-limit batches that exclude non-ready package work
Publish packages to registriesmonochange publish packages --output <path>You want cargo publish, npm publish, deno publish, or dart pub publish style package publication
Bootstrap release packagesmonochange publish placeholderYou need a release-record-scoped placeholder bootstrap artifact before rerunning readiness
Create post-merge release tagsmonochange step tag-release --from HEADYou merged a monochange release commit and now need to create and push its declared tag set
Repair a recent releasemonochange step retarget-release --from <tag> --target <commit>You need to retarget a just-created release to a later commit
Publish hosted/provider releasesmonochange step publish-releaseYou want GitHub/GitLab/Gitea release objects from prepared release state

monochange step publish-readiness performs non-mutating registry checks before monochange step publish-packages. For built-in Cargo publishes to crates.io it also verifies current manifest publishability: publish = false blocks publishing, publish = [...] must include crates-io, description must be set, and either license or license-file must be set. Workspace-inherited Cargo metadata is accepted, and already-published versions remain non-blocking in readiness reports. The artifact fingerprints monochange.toml, package manifests, lockfiles, and registry/tooling files, so rerun monochange step publish-readiness after those inputs change. monochange step plan-publish-rate-limits --readiness <path> validates the artifact for planning and limits rate-limit batches to package ids that are ready in both the artifact and the fresh local readiness check. monochange step publish-packages publishes directly from prepared release or HEAD release state and does not require the readiness artifact. If readiness shows missing first-time registry packages, run monochange step placeholder-publish, then rerun readiness before real publishing.

What monochange can do

  • discover Cargo, npm/pnpm/Bun, Deno, Dart, Flutter, Python, and Go packages
  • normalize dependency edges across ecosystems
  • coordinate shared package groups from monochange.toml
  • compute release plans from explicit change input
  • expose repository-defined workflow commands as monochange run <command> from [cli.<command>] definitions
  • run config-defined release commands from .changeset/*.md
  • render changelogs through structured release notes and configurable formats
  • emit stable release-manifest JSON for downstream automation
  • preview or publish provider releases and release requests from typed command steps and shared release data
  • inspect durable release records from tags or descendant commits with monochange step release-record
  • create post-merge release tags from a merged release commit with monochange step tag-release --from HEAD
  • repair a recent source/provider release by retargeting its release tags with monochange step retarget-release
  • inspect changeset context and review metadata with monochange step diagnose-changesets for both human and automation workflows
  • apply Rust semver evidence when provided
  • expose a bundled assistant skill plus a stdio MCP server with monochange mcp
  • publish the CLI as @monochange/cli and the bundled agent skill as @monochange/skill
  • publish end-user documentation through the mdBook in docs/

What the JSON output includes

Discovery output includes:

  • normalized package records
  • dependency edges
  • release groups derived from configured groups
  • warnings

Release-plan output includes:

  • per-package bump decisions
  • synchronized group outcomes
  • compatibility evidence
  • warnings and unresolved items
  • optional fileDiffs previews when you request --diff

Contributing to monochange itself

If you are working on the monochange repository, run the full local validation suite before opening a PR:

lint:all
test:all
build:all
build:book