# bumpp

> Bump version, commit changes, tag, and push to Git

Latest version **12.3.0** (published 2026-09-03) · MIT license · 0 weekly downloads

## Install

```sh
npm install bumpp
pnpm add bumpp
yarn add bumpp
bun add bumpp
```

Provides the command `bumpp`.

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 12.3.0 |
| Published | 2026-09-03 |
| First published | 2020-07-20 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM |
| Node | ^22.18.0 \|\| ^24.11.0 \|\| >=26.0.0 |
| Dependencies | 9 |
| Unpacked size | 240.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 961 |
| Maintainers | antfu |
| Keywords | version, bump, npm, node, bower, package, git, tag, push, prompt |

## Links

- npm: https://www.npmjs.com/package/bumpp
- Repository: https://github.com/antfu-collective/bumpp
- npm.io page: https://npm.io/package/bumpp

## Dependencies (9)

- [cac](https://npm.io/package/cac.md) ^7.0.0
- [yaml](https://npm.io/package/yaml.md) ^2.9.0
- [verkit](https://npm.io/package/verkit.md) ^0.4.0
- [tinyexec](https://npm.io/package/tinyexec.md) ^1.3.0
- [unconfig](https://npm.io/package/unconfig.md) ^7.5.0
- [tinyglobby](https://npm.io/package/tinyglobby.md) ^0.2.17
- [jsonc-parser](https://npm.io/package/jsonc-parser.md) ^3.3.1
- [args-tokenizer](https://npm.io/package/args-tokenizer.md) ^0.3.0
- [package-manager-detector](https://npm.io/package/package-manager-detector.md) ^1.8.0

## Alternatives

- [@expo/fingerprint](https://npm.io/package/@expo/fingerprint.md) — 6.2M weekly downloads
- [@azure/monitor-opentelemetry-exporter](https://npm.io/package/@azure/monitor-opentelemetry-exporter.md) — 850.0K weekly downloads
- [@azure/monitor-opentelemetry](https://npm.io/package/@azure/monitor-opentelemetry.md) — 624.0K weekly downloads
- [@posthog/ai](https://npm.io/package/@posthog/ai.md) — 423.3K weekly downloads
- [fakefilter](https://npm.io/package/fakefilter.md) — 63.9K weekly downloads

## Recent versions

- 12.3.0 (latest) — 2026-09-03
- 12.2.3 — 2026-09-03
- 12.2.2 — 2026-08-26
- 12.2.1 — 2026-08-13
- 12.2.0 — 2026-08-06
- 12.1.1 — 2026-07-29
- 12.1.0 — 2026-07-28
- 12.0.0 — 2026-07-21
- 11.1.0 — 2026-05-07
- 11.0.1 — 2026-03-16
- 11.0.0 — 2026-03-14
- 10.4.1 — 2026-02-05
- 10.4.0 — 2026-01-13
- 10.3.2 — 2025-11-27
- 10.3.1 — 2025-10-06
- … 49 more at https://npm.io/package/bumpp/versions

## README

# bumpp

[![NPM version](https://img.shields.io/npm/v/bumpp?color=a1b858&label=)](https://www.npmjs.com/package/bumpp)

Forked from [`version-bump-prompt`](https://github.com/JS-DevTools/version-bump-prompt)

<!-- eslint-disable-next-line markdown/heading-increment -->
###### Changes in this fork

- Renamed to `bumpp` - so you can use `npx bumpp` directly.
- Use the current version's `preid` when available.
- Confirmation before bumping.
- Enable `--commit` `--tag` `--push` by default. (opt-out by `--no-push`, etc.)
- `-r` or `--recursive` to bump all packages in the monorepo.
- `--execute` to execute the command, or execute a function before committing.
- Conventional Commits by default.
- Ships ESM and CJS bundles.
- Supports config file `bump.config.ts`:

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

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

## Template tokens

The commit message, tag name, and pull request branch/title/body all support
named tokens. This is the recommended template style:

| Token           | Description                                        | Example      |
| --------------- | -------------------------------------------------- | ------------ |
| `{version}`     | The new version number                             | `1.2.3`      |
| `{oldVersion}`  | The previous version number                        | `1.2.2`      |
| `{tag}`         | The formatted tag name                             | `v1.2.3`     |
| `{releaseType}` | The release type (empty for explicit versions)     | `patch`      |
| `{major}`       | The major segment of the new version               | `1`          |
| `{minor}`       | The minor segment of the new version               | `2`          |
| `{patch}`       | The patch segment of the new version               | `3`          |
| `{date}`        | The current date (`YYYY-MM-DD`, local time)        | `2026-07-28` |

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

> The legacy `%s` placeholder (replaced with the new version) still works but is
> soft-deprecated in favour of `{version}`. If a template contains any named
> token, `%s` substitution is disabled for that template.

## Releasing via a Pull Request

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. The
`--pr` flag lets you drive releases through a pull request instead: a maintainer
approves and merges it, and CI tags the merge commit and publishes.

```sh
bumpp --pr
```

With `--pr`, bumpp:

1. Checks the working tree is clean, that you are on the base branch (the remote
   default branch, detected via `origin/HEAD`), and that it is not behind its
   remote.
2. Creates a release branch (`release/v{version}` by default).
3. Bumps the version in your files and runs the `execute` script, if any.
4. Commits the bump — **no tag is created locally**; the tag is created by CI
   after the pull request is merged.
5. Pushes the branch, then switches you back to your original branch.
6. Offers to open a pull request via the local [`gh`](https://cli.github.com)
   CLI (auto-created with `--yes`). If `gh` is unavailable, it prints a link to
   open the pull request manually.

If an open release pull request for the same version already exists on the same
release branch and was opened by you, bumpp updates it instead of creating a
duplicate — the branch is force-pushed and the pull request's title and body are
refreshed. Re-run `bumpp --pr` and pick the same version to amend an in-progress
release PR.

The `release/` branch prefix is the marker CI uses to recognise a release pull
request, so keep it unless you also update your workflow.

### Configuration

`--pr` toggles the feature on the CLI. For finer control, use the object form in
`bump.config.ts`:

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

export default defineConfig({
  pr: {
    branch: 'release/v{version}', // release branch name template
    base: 'main', // PR base branch (defaults to origin/HEAD)
    title: 'chore: release {tag}', // defaults to the release commit message
    body: '{oldVersion} → {version}', // template string, or a function receiving the tokens
    draft: false, // open the PR as a draft
  },
})
```

`pr` requires `push` to be enabled, and implies that no tag is created locally.

### GitHub Actions setup

Because a tag pushed with the default `GITHUB_TOKEN` will **not** trigger another
workflow (GitHub's recursion guard), the release runs in a single workflow that
reacts to the release pull request being merged, creates the tag, and publishes:

```yaml
# .github/workflows/release-pr.yml
name: Release (PR merged)

on:
  pull_request:
    types: [closed]

# 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/')
    runs-on: ubuntu-latest
    permissions:
      contents: write # create the tag, release, and read the repo
      id-token: write # npm OIDC trusted publishing
    steps:
      - uses: actions/checkout@v5
        with:
          # Check out the merge commit so package.json has the bumped version
          ref: ${{ github.event.pull_request.merge_commit_sha }}
          fetch-depth: 0

      - uses: actions/setup-node@v5
        with:
          node-version: 22
          registry-url: https://registry.npmjs.org

      - name: Read version
        id: version
        run: echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT"

      - name: Create tag
        uses: actions/github-script@v8
        with:
          script: |
            await github.rest.git.createRef({
              owner: context.repo.owner,
              repo: context.repo.repo,
              ref: `refs/tags/v${{ steps.version.outputs.version }}`,
              sha: context.payload.pull_request.merge_commit_sha,
            })

      - run: npm ci
      - run: npm run build --if-present

      # Generate the GitHub Release notes from conventional commits
      - run: npx changelogithub
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      # Publish with npm OIDC trusted publishing (no NPM_TOKEN needed).
      # Requires npm CLI >= 11.5.1 and a configured trusted publisher on npmjs.com.
      - run: npm publish
```

Then protect `main` (Settings → Branches): require a pull request and at least
one approval before merging. Now the only way to cut a release is `bumpp --pr` →
review → merge, and CI does the rest.

> If you already have a workflow triggered by `v*` tags, you can instead push the
> tag from a merge-triggered job using a Personal Access Token or a GitHub App
> token (not `GITHUB_TOKEN`) so the tag push triggers your existing pipeline.

### Security

This workflow publishes to npm, so it must never run untrusted code with
privileged credentials. The example is designed to be safe:

- **It uses `pull_request`, not `pull_request_target`.** The workflow definition
  is always read from your default branch, so a pull request cannot modify the
  release logic. (`pull_request_target` would run with a read/write token and
  your secrets even for forks — never use it here.)
- **It requires the release branch to live in your repository**
  (`head.repo.full_name == github.repository`). The `release/*` branch name is
  attacker-controllable from a fork, so the name check alone is *not* enough — a
  forker could open a PR from a branch called `release/v9.9.9`. The same-repo
  guard ensures the job never even checks out or runs fork-authored code (and
  `bumpp --pr` always pushes the release branch to your repo, so legitimate
  releases are unaffected). As an additional backstop, GitHub gives fork pull
  requests a read-only `GITHUB_TOKEN` with no secrets or OIDC, so the tag and
  publish steps would fail rather than leak anyway.
- **Protect `main`** with required reviews so a release can only be merged by a
  maintainer.

For extra defense-in-depth, run the publish step in a dedicated
[GitHub Environment](https://docs.github.com/en/actions/how-tos/deploy/configure-and-manage-deployments/manage-environments)
with required reviewers, so npm publishing needs an explicit second approval:

```yaml
jobs:
  release:
    environment: release # npm publish now needs a second approval
    # ...rest of the job as above
```

---
_Source: https://npm.io/package/bumpp · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
