Changesets
Versioning and changelog management with Changesets for coordinated monorepo package releases
You are an expert in Changesets for managing versioning, changelogs, and publishing across monorepo packages. ## Key Points - **`linked`** — Packages that should always have the same version. If one bumps major, they all bump major. - **`fixed`** — Packages that always share the exact same version number. - **`access`** — `"public"` for scoped packages on npm, `"restricted"` for private. - **`updateInternalDependencies`** — Automatically bump internal consumers when a dependency changes. - **`ignore`** — Packages excluded from versioning (docs sites, dev tools). 1. Which packages have changed? 2. Is each change major, minor, or patch? 3. Provide a summary of the change. - Bumps `version` in each affected `package.json` - Updates `CHANGELOG.md` in each package - Removes consumed changeset files - Updates internal dependency ranges ## Quick Example ```bash pnpm add -D @changesets/cli pnpm changeset init ``` ```bash pnpm changeset ```
skilldb get monorepo-skills/ChangesetsFull skill: 205 linesChangesets — Monorepo Management
You are an expert in Changesets for managing versioning, changelogs, and publishing across monorepo packages.
Core Philosophy
Overview
Changesets is a versioning and release tool designed for monorepos. It allows developers to declare their intent to release (a "changeset") alongside their code changes. At release time, Changesets aggregates all pending changesets, bumps versions according to semver, updates changelogs, and publishes packages. This decouples "deciding what changed" from "performing the release."
Setup & Configuration
Installation
pnpm add -D @changesets/cli
pnpm changeset init
This creates a .changeset/ directory with a config.json.
.changeset/config.json
{
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [["@myorg/ui", "@myorg/ui-icons"]],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": ["@myorg/docs", "@myorg/storybook"],
"privatePackages": {
"version": true,
"tag": false
}
}
Key Configuration Options
linked— Packages that should always have the same version. If one bumps major, they all bump major.fixed— Packages that always share the exact same version number.access—"public"for scoped packages on npm,"restricted"for private.updateInternalDependencies— Automatically bump internal consumers when a dependency changes.ignore— Packages excluded from versioning (docs sites, dev tools).
Core Patterns
Creating a Changeset
pnpm changeset
This interactive prompt asks:
- Which packages have changed?
- Is each change major, minor, or patch?
- Provide a summary of the change.
It creates a markdown file in .changeset/:
---
"@myorg/ui": minor
"@myorg/utils": patch
---
Added new Button variant and updated utility helpers for color tokens.
Versioning Packages
pnpm changeset version
This consumes all pending changeset files and:
- Bumps
versionin each affectedpackage.json - Updates
CHANGELOG.mdin each package - Removes consumed changeset files
- Updates internal dependency ranges
Publishing
pnpm changeset publish
Publishes all packages with new versions to the registry. Packages that haven't changed are skipped.
CI Automation with GitHub Actions
name: Release
on:
push:
branches: [main]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
- run: pnpm run build
- name: Create Release PR or Publish
uses: changesets/action@v1
with:
publish: pnpm changeset publish
version: pnpm changeset version
title: 'chore: version packages'
commit: 'chore: version packages'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
The changesets/action creates a "Version Packages" PR that stays up to date. Merging it triggers the publish step.
Snapshot Releases
For pre-release testing without full version bumps:
# Create a snapshot release
pnpm changeset version --snapshot canary
pnpm changeset publish --tag canary --no-git-tag
# Produces versions like 1.2.3-canary-20240315120000
Pre-releases
# Enter pre-release mode
pnpm changeset pre enter beta
# Create changesets and version as usual
pnpm changeset
pnpm changeset version
# Produces versions like 1.2.0-beta.0
# Exit pre-release mode when ready
pnpm changeset pre exit
pnpm changeset version
# Produces the stable version 1.2.0
Custom Changelog Generation
{
"changelog": [
"@changesets/changelog-github",
{ "repo": "myorg/myrepo" }
]
}
This links PRs and authors in the generated changelog entries.
Best Practices
- Require changesets in PRs — Use the Changesets bot or a CI check to ensure every user-facing PR includes a changeset.
- Write user-facing summaries — Changeset descriptions become changelog entries. Write them for consumers, not developers.
- Use
linkedfor tightly coupled packages — UI component packages that must stay in sync should be linked. - Use
ignorefor private packages — Docs sites, example apps, and dev tools don't need versioning. - Automate with the GitHub Action — The Changesets GitHub Action handles the version PR and publish flow automatically.
- Use snapshot releases for testing — Publish canary versions from feature branches so consumers can test before merge.
- Review version PRs carefully — The aggregated version PR shows all version bumps and changelog entries; review it for accuracy.
Common Pitfalls
- Forgetting to add a changeset — PRs merged without changesets won't be included in the next release. Enforce with CI checks.
- Wrong semver level — A breaking API change marked as
patchwill surprise consumers. Review changeset semver levels in code review. - Internal dependency cascades — With
updateInternalDependencies: "patch", changing one package can trigger version bumps across many packages. This is correct but can be surprising. - Not building before publish —
changeset publishrunsnpm publishwhich uses thefilesfield. Ensuredist/is built and up to date. - Pre-release mode confusion — Forgetting to exit pre-release mode means all subsequent versions will be pre-releases. Always
changeset pre exitbefore the stable release.
Anti-Patterns
Over-engineering for hypothetical scale. Building for millions of users when you have hundreds adds complexity without value. Solve today's problems first.
Ignoring the existing ecosystem. Reinventing functionality that mature libraries already provide well wastes time and introduces unnecessary risk.
Premature abstraction. Creating elaborate frameworks and utilities before you have enough concrete cases to know what the abstraction should look like produces the wrong abstraction.
Neglecting error handling at boundaries. Internal code can trust its inputs, but system boundaries (user input, APIs, file I/O) require defensive validation.
Skipping documentation for obvious code. What is obvious to you today will not be obvious to your colleague next month or to you next year.
Install this skill directly: skilldb add monorepo-skills
Related Skills
CI Optimization
CI/CD optimization for monorepos including affected detection, caching strategies, and parallel execution
Dependency Management
Managing internal package dependencies, versioning strategies, and dependency graph health in monorepos
Lerna
Multi-package repository management with Lerna for versioning, publishing, and task orchestration
Nx
Monorepo development with Nx including project graph, generators, executors, and computation caching
Pnpm Workspaces
Managing monorepo packages with pnpm workspaces including linking, filtering, and dependency hoisting
Shared Configs
Sharing ESLint, TypeScript, Prettier, and other tool configurations across monorepo packages