How to Publish Only the Changed Packages in a Monorepo
The reliable signal for what to publish is a version diff: publish a package only when its local version is not already on the registry.
Rather than diffing files, most monorepo tools decide what to publish by comparing the local package.json version to the latest published version. Changesets, pnpm, Lerna from-git, and Rush all follow this version-diff rule.
How each tool decides
| Tool | What it publishes |
|---|---|
| changeset publish | Packages whose version is ahead of the registry |
| pnpm publish -r | Packages with a version not yet published |
| lerna publish from-git | Versions matching git tags just created |
| rush publish | Projects whose version increased via change files |
Manual guard
Terminal
# Skip publish if this version is already on the registry
NAME=$(node -p "require('./package.json').name")
VER=$(node -p "require('./package.json').version")
if npm view "$NAME@$VER" version >/dev/null 2>&1; then
echo "$NAME@$VER already published, skipping"
else
npm publish --access public
fiGotchas
- Version-diff publishing is idempotent, so a re-run after a partial failure only publishes what is still missing.
- Do not gate publish on changed files alone; a dependency bump can require publishing a package whose own files did not change.
Related guides
How to Avoid Partial Releases in a MonorepoReduce the blast radius of a mid-publish failure by building all packages before publishing any, and by makin…
How to Bump Dependent Packages When a Dependency ChangesKeep internal package interdependencies correct by bumping dependents when a dependency releases, using the u…