beachball: a change-file workflow for versioning a JavaScript monorepo
The Sunniest Semantic Version Bumper
At a glance
- What is it?
- beachball makes a developer write a change file describing what they changed and whether it breaks the API, and the tooling then decides what version to bump and what the changelog says. It grew out of Microsoft and now runs on Yarn and npm, but the interesting wrinkle is that the v3 rewrite lives on main while the stable line sits on a v2 branch.
- Who is it for?
- Adopt beachball if you run a JavaScript monorepo with many published packages and you want versioning decisions driven by explicit change files rather than inferred from commit messages. Do not adopt it if your repository publishes a single package or your team refuses to write a file per change, because that is the whole workflow.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A change file per pull request is the unit of work
beachball is a version bumping tool, and its central mechanism is a file that a developer commits alongside their change. The README points at the beachball-change-file skill in the skills directory, whose stated purpose is to walk an agent through generating a change file, because AI agents cannot use interactive prompts. That single sentence tells you the whole design. The normal flow is that a developer describes their change in a change file, which records what was changed and how significant it is, and the tooling reads the collected change files to decide the next version and to write the changelog entry. The repository has a change/ directory at its root, and the scripts in package.json name the operations: beachball change to create a change file, beachball check to verify that the required files are present, and beachball bump to perform the version bump and publish. The tool exists because commit messages are not a reliable record of intent, and a change file forces the developer to state the breaking-ness explicitly rather than leaving it to be guessed from a diff.
Two lines of development, and you have to pick one
The README's second paragraph is the first thing any adopter should read. It states that main is currently the development branch for beachball v3, which is in alpha, and that the code for beachball v2, published as latest, is in the v2 branch. It then says that a pull request with a non-breaking change should target the v2 branch, and that you can try the new version with beachball@next, with a migration guide at docs/overview/v3-migration.md. So the project is mid-major-version, with the stable line on a side branch and the rewrite on main. The practical consequence is that a contributing pull request and a consuming dependency resolve to different branches depending on what you want, and the default install still gives you v2. If you are evaluating beachball for a new repository, the honest question is whether you want the alpha line or the stable one, and the answer is probably the stable one until the v3 branch stabilises.
Configuration lives in two root files you can edit
The repository root carries beachball.config.js and beachball.release.js, and the scripts distinguish between them. The ordinary commands run beachball with no configuration argument, so they pick up the default beachball.config.js, while the release script is explicit and runs beachball -c beachball.release.js, which suggests the release configuration differs from the day-to-day one, probably in how versions are published rather than how they are chosen. The root also holds lage.config.js for the build tool, renovate.json5 and a renovate/ directory of presets, syncpack.config.js for keeping workspace dependency versions consistent, and lint-staged.config.mjs. That set of files describes a monorepo with a strict policy about how versions relate to each other, and beachball is the piece that decides which versions change. The package.json itself is private, named @microsoft/beachball-monorepo at version 0.0.0, with the published tool living in packages/beachball.
The commands your CI will run
The package.json scripts are the reference for how this is wired into a build. The main ones are:
"scripts": {
"build": "lage build bundle",
"bump": "beachball bump",
"change": "beachball change",
"checkchange": "beachball check",The other scripts fill in the supporting work. beachball:release runs beachball -c beachball.release.js, format and format:check run prettier, lint runs lage lint, test runs lage test, and syncpack:check and syncpack:update run the syncpack lint and fix. There is also update-snapshots for lage, and the prepare script wires up husky for git hooks. The split between lage and beachball is worth noting: lage is the build and task runner, and beachball sits beside it as the versioning tool. The engines field requires Node ^22.18.0 || >=24, and the workspaces list covers actions/*, packages/*, renovate, scripts, skills and yarn-plugins/*.
Three GitHub Actions that encode the policy
The repository hosts three reusable GitHub Actions, and each one is a policy expressed as an action. check-for-modified-files checks for modified files in a pull request and fails if any are found, which is how a repository enforces that a change file was added rather than left out. install-beachball installs the correct version of beachball for a standalone check change files workflow. should-release determines whether a release workflow run is needed based on the presence of change files or other files, which is the mechanism that stops an empty release from being triggered. The point of the three together is that the policy does not depend on a human remembering. Combined with the beachball check command, a pull request without a change file fails, and a repository with no change files does not start a release. That is a design that a team can rely on without trusting anyone's memory, and it is the argument for the tool over a hand-rolled script.
Other tools that live in the same monorepo
beachball is one of several packages in packages/, and the README explains why some of them are co-located. proper-changelog exists because GitHub releases are useful in some ways but are poor as changelogs if you need to look at changes across multiple versions or work out when a specific change was introduced. It reads GitHub releases and generates a single markdown changelog. That is a real problem for a monorepo with many packages, and it is a problem beachball itself does not solve. p-graph is the promise graph used by beachball itself, which is a nice detail, since it means the tool dogfoods its own dependency. @microsoft/esrp-npm-release is for Microsoft teams using ESRP Release, which is the internal publishing path at Microsoft rather than something general users need. The Renovate presets moved from microsoft/m365-renovate-config and predate some of Dependabot's expanded capabilities, and the README says they are still used by some repositories.
MIT licensed, no tags, and a v3 line still in alpha
The licence is MIT, with the LICENSE file at the repository root. The repository is not archived and the last push was on 2026-10-15, so work is landing, and the presence of an AGENTS.md file at the root, an .agents/ directory and a skills/ directory with the change-file skill, shows the project is being maintained with AI tooling in mind rather than against it. There are no GitHub releases, which is consistent with a tool that publishes itself to npm rather than as a binary, and consistent with a repository whose released artefacts are the npm packages rather than tags on this repo. The open question for an adopter is the v3 alpha. The stable line is on a branch, the rewrite is on main, and the guide to move between them is docs/overview/v3-migration.md. Until that migration is something your team has actually read, staying on v2 is the lower-risk choice, and it is what the default install gives you.
Editorial conclusion
Adopt beachball if you run a JavaScript monorepo with many published packages and you want versioning decisions driven by explicit change files rather than inferred from commit messages. Do not adopt it if your repository publishes a single package or your team refuses to write a file per change, because that is the whole workflow. Before you commit, decide which line you are on, since main carries the v3 alpha and the v2 branch carries the stable code, check the beachball.config.js file that sits at the repository root for your own configuration, and read the v3 migration guide before switching branches.
Frequently asked questions
What is beachball?
It is an MIT licensed tool from Microsoft for versioning a JavaScript monorepo through change files, where a developer commits a file describing what changed and whether it breaks the API. The tooling then determines the version bump and the changelog entry from the collected change files.
How do I use beachball in a repository?
The package.json scripts show the commands: beachball change to create a change file, beachball check to verify the required files are present, and beachball bump to perform the version bump and publish. Configuration goes in beachball.config.js at the repository root, with a separate beachball.release.js used by the beachball:release script.
What is the difference between the beachball main and v2 branches?
The README states that main is the development branch for beachball v3, which is alpha, while the v2 code published as latest lives in the v2 branch. Non-breaking pull requests should target the v2 branch, and the v3 alpha can be tried with beachball@next using the migration guide.
Does beachball work with AI coding agents?
The repository ships a beachball-change-file skill that walks an agent through generating a change file, because agents cannot use interactive prompts. The AI integration documentation is linked from the README as well.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/microsoft-beachball)Was this useful?