CLI tool
antfu-collective/bumpp avatar
antfu-collective/bumpp

bumpp: how a version bump becomes a commit, a tag, and a pushed branch

Interactive CLI that bumps your version numbers and more

961 stars70 forksTypeScriptMIT

At a glance

What is it?
bumpp is an interactive TypeScript CLI that raises a package version, writes a conventional commit, tags and pushes it by default, and can hand the release over to a pull request and CI instead.
Who is it for?
bumpp fits solo maintainers and small teams who want a conventional commit, a tag, and a push from one command, and it fits team workflows only if you add the release pull request workflow and protect the base branch. Skip it if your release process needs signing, changelog generation, or a publish step the tool cannot express, or if your Node version sits below 22.18.0.
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 52 days 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 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

bumpp owns the whole release commit, not just the version string

bumpp is a TypeScript command line tool for the moment after you decide a package needs a new number. The problem it solves is narrow and real: raising a version touches a file, a commit message, a tag, and a remote, and doing those four things by hand means four chances to get them out of sync. The project description calls it an interactive CLI that bumps version numbers and more, and package.json spells the contract out as bump version, commit changes, tag, and push to Git.

The fork starts from version-bump-prompt and changes the working model. bumpp prompts for a release type and lets tokens fill in the rest. Where the original left committing and tagging to you, this fork enables them by default, so a single invocation can move a project from a clean tree to a pushed tag. A confirmation step appears before anything is written, so the defaults are not a silent trap.

That default set matters for a specific audience: a solo maintainer or a small team that wants releases to happen in the conventional commit format their tooling already expects, without writing a script per repository. The feature list also covers recursive bumps for monorepos, a config file for options, and an execute hook that can run a command before the commit lands. Commit messages, tag names, and pull request titles all draw from the same token table, so one choice of version propagates through the whole release.

Named tokens replace the old %s placeholder in commit and tag templates

The template system is the part of bumpp that goes slightly beyond plain substitution. The README presents a table of named tokens: {version} and {oldVersion} for the new and previous numbers, {tag} for the formatted tag, {releaseType}, the {major}, {minor} and {patch} segments, and {date} in YYYY-MM-DD local time. A commit message or a pull request title can use any of them, and the documented example wires {tag} into a commit subject and {version} into the tag itself.

A release call then looks like this:

sh
bumpp --commit "chore: release {tag}" --tag "{version}"

The {version} token resolves to a bare 1.2.3 while {tag} resolves to the prefixed v1.2.3 form, which lets one version feed two differently shaped strings without any shell arithmetic. The README also keeps the older %s placeholder alive but calls it soft-deprecated in favour of {version}, and it sets one clear rule: if a template contains any named token, %s substitution is disabled for that template. That is a sensible guard, since silently mixing two placeholder styles in one string produces the kind of commit subject that surprises you later.

The same tokens feed the pull request title and body, and the config file allows the body to be a template string or a function receiving the tokens, which covers cases where a release note needs something computed rather than substituted.

Your first bump with npx bumpp and a bump.config.ts

Getting bumpp into a project takes one command, because the fork renamed itself so the runner shortcut works without a global install.

sh
npx bumpp

That runs the published package, prompts for a release type, and by default commits, tags, and pushes. The repository also exposes a bin entry named bumpp that points at bin/bumpp.mjs, so a project that installs bumpp as a dev dependency gets a local binary it can call from its own scripts.

Options that you would otherwise repeat on every invocation belong in a config file. The documented shape is a TypeScript file that imports defineConfig from the package itself:

ts
// bump.config.ts
import { defineConfig } from 'bumpp'

export default defineConfig({
  // ...options
})

Because the config is a real TypeScript module rather than a JSON file, options can be expressions and the token templates stay typed. The token table still applies to every template string you place inside it, so the commit message, the tag name, and the pull request fields can all be written once and reused on every release. The project itself keeps a bump.config.ts at the root of the repository, and its package.json declares an npm script named release that runs pnpm run bumpp, which is the shape most consuming projects copy.

The --pr flow pushes a release branch and leaves the tag to CI

The --pr flag is where bumpp stops being a local convenience and becomes a release mechanism. The README is explicit about the problem it solves: pushing version-bump commits and tags straight to main is convenient for solo projects, but on a team it bypasses branch protection and code review.

sh
bumpp --pr

With --pr, bumpp runs a fixed sequence. It checks that the working tree is clean, that you are on the base branch as detected from origin/HEAD, and that you are not behind its remote. It creates a release branch named release/v{version} by default, bumps the version in your files, runs the execute script if you have one, and commits. No tag is created locally, because CI creates the tag after the merge. The branch is pushed, you are switched back to your original branch, and bumpp offers to open the pull request through the local gh CLI, with the pull request auto-created when you pass --yes. If gh is unavailable, it prints a link so you can open the pull request manually.

Re-running the command is safe while a release is in flight. If an open release pull request for the same version already exists on the same release branch and you opened it, bumpp updates it instead of creating a duplicate: the branch is force pushed and the pull request title and body are refreshed. The finer controls live in the object form of the config, where the branch template, base branch, title, body, and a draft flag can all be set explicitly.

The release/ prefix is what CI keys on to allow the privileged job

The branch name is not cosmetic. The README states that the release/ branch prefix is the marker CI uses to recognise a release pull request, and that you should keep it unless you also update your workflow.

yaml
# Only run for merged release/* pull requests that originate from THIS repo.
# The `head.repo.full_name == github.repository` check is essential: it stops a
# fork from opening a PR whose branch is named `release/*` and having this
# privileged workflow run against it. See "Security" below.
jobs:
  release:
    if: >-
      github.event.pull_request.merged == true &&
      github.event.pull_request.head.repo.full_name == github.repository &&
      startsWith(github.event.pull_request.head.ref, 'release/')

The head.repo.full_name condition is the part worth understanding. Without it, a fork could open a pull request against the upstream repository with a branch named release/something and trigger a job holding contents: write and id-token: write permissions. The workflow shipped with the project also explains why a single workflow reacts to the merge: a tag pushed with the default GITHUB_TOKEN will not trigger another workflow, because of GitHub recursion guard. The job checks out the merge commit, reads the version out of package.json, creates the tag, installs with npm ci, generates release notes with npx changelogithub, and publishes using npm OIDC trusted publishing with no NPM_TOKEN, which the docs say needs npm CLI 11.5.1 or newer and a trusted publisher configured on npmjs.com.

After copying the workflow, the README tells you to protect main in the branch settings by requiring a pull request and at least one approval, so the only route to a release becomes bumpp --pr, review, merge.

Where bumpp is the wrong tool

bumpp has limits worth knowing before you wire it into a release pipeline.

First, --pr requires push to be enabled and implies that no local tag is created, so a script that expects to find a tag right after the command will not find one. Second, the automated pull request path depends on the local gh CLI, and without gh installed the fallback is a printed link you have to follow by hand.

Third, the monorepo story is thinner than the flag list suggests. The README advertises -r or --recursive to bump all packages in the monorepo, and the repository ships pnpm-workspace.yaml and a pnpm-lock.yaml, but the README does not explain how a single version is derived across packages that carry different versions. If you publish many independent packages, check that behaviour against your own layout before trusting it.

Fourth, the runtime range is narrow. package.json declares engines node ^22.18.0 || ^24.11.0 || >=26.0.0, so a repository pinned to Node 18 or 20 cannot run the current release at all. The fork ships ESM and CJS bundles, and the published exports point at dist/index.mjs, dist/cli.mjs, and package.json, so code that imports the API instead of running the binary needs to check those paths.

Finally, bumpp creates commits, tags, and pull requests. Signing, changelog generation, and publishing stay in your workflow.

MIT licensed, pnpm driven, last pushed on 2026-09-03

The project is MIT licensed, and package.json names Anthony Fu and James Messinger as the authors, with the fork lineage from version-bump-prompt visible in the project README.

On maintenance, the last push was on 2026-09-03, and the recent release list shows v12.3.0 and v12.2.3 both on 2026-09-03 with v12.2.2 on 2026-08-26. The version in package.json is 12.3.0, the declared package manager is [email protected], and the root holds pnpm-lock.yaml and pnpm-workspace.yaml, which is the layout behind the monorepo and recursive bump features. The build script runs tsdown, the tests run under vitest, and a typecheck script uses tsgo.

The upgrade cost is low for most users, since the tool is invoked rather than imported. The CLI surface is documented through flags including --commit, --tag, --push, --no-push, --recursive, --execute, --pr, and --yes, and a flag rename would break release scripts silently, so read the release notes for a version before you pin it in a pipeline.

Editorial conclusion

bumpp fits solo maintainers and small teams who want a conventional commit, a tag, and a push from one command, and it fits team workflows only if you add the release pull request workflow and protect the base branch. Skip it if your release process needs signing, changelog generation, or a publish step the tool cannot express, or if your Node version sits below 22.18.0. Before the first run, check that the working tree is clean and you sit on the base branch, that the release/ branch prefix matches the workflow you copied, and that the commit and tag templates produce the strings your existing tooling expects.

Frequently asked questions

How do I install and run bumpp in a Node project?

Run npx bumpp from the project root, because the fork renamed itself to bumpp so the runner shortcut works without a global install. The package also declares a bin entry named bumpp, so installing it as a dev dependency gives you a local binary.

Does bumpp support monorepos?

Yes, the README lists -r or --recursive to bump all packages in the monorepo, and the repository ships pnpm-workspace.yaml and pnpm-lock.yaml. The README does not explain how one version is chosen across packages that carry different versions.

How does bumpp release through a pull request instead of a direct push?

Run bumpp --pr. It checks that the working tree is clean and that you are on the base branch, creates a release/v{version} branch, commits the bump without creating a local tag, pushes the branch, and offers to open the pull request with the local gh CLI. CI creates the tag after the merge.

Which Node versions does bumpp support?

package.json declares engines node ^22.18.0 || ^24.11.0 || >=26.0.0, so Node 18 and Node 20 sit outside the supported range for the current release.

Official sources

  1. antfu-collective/bumpp on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/antfu-collective-bumpp.svg)](https://hysenlabs.com/projects/antfu-collective-bumpp)

Was this useful?