Automated semver compliant package publishing
semantic-release is a tool that removes the manual overhead of package releases by analyzing commit messages to determine version bumps, generating changelogs, and publishing to npm—all without human intervention. It parses commits following Conventional Commits specification to decide whether changes warrant a major, minor, or patch release, then executes the entire release workflow through a plugin system.
With over 2 million weekly downloads, it has become a standard solution for teams wanting consistent, predictable releases tied directly to their commit history. Rather than maintaining version numbers in package.json manually, semantic-release uses Git tags as the source of truth, calculating the next version based on commit types (feat:, fix:, BREAKING CHANGE:) since the last release. This approach eliminates human error in versioning and ensures SemVer compliance.
The tool runs exclusively in CI/CD environments (GitHub Actions, GitLab CI, CircleCI, etc.), triggered on merge to protected branches. Its plugin architecture allows teams to customize the release workflow—from verifying credentials and running tests, to updating documentation, committing changelog files, and creating GitHub releases. Each plugin executes in a defined lifecycle step (verifyConditions, prepare, publish, success, fail), providing hooks into every stage of the release process.
semantic-release is designed for teams that have adopted Conventional Commits and want to enforce release discipline through automation rather than process documentation. It's particularly valuable in monorepos, microservice architectures, and open-source projects where release frequency is high and consistency matters.
// .releaserc.json - Configuration file in project root
{
"branches": ["main", {"name": "beta", "prerelease": true}],
"plugins": [
["@semantic-release/commit-analyzer", {
"preset": "conventionalcommits",
"releaseRules": [
{"type": "docs", "scope": "README", "release": "patch"},
{"type": "refactor", "release": "patch"},
{"type": "perf", "release": "patch"}
]
}],
["@semantic-release/release-notes-generator", {
"preset": "conventionalcommits"
}],
["@semantic-release/changelog", {
"changelogFile": "CHANGELOG.md"
}],
["@semantic-release/npm", {
"npmPublish": true,
"tarballDir": "dist"
}],
["@semantic-release/git", {
"assets": ["CHANGELOG.md", "package.json", "package-lock.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}],
["@semantic-release/github", {
"assets": [{"path": "dist/*.tgz", "label": "Distribution"}]
}]
]
}
// GitHub Actions workflow - .github/workflows/release.yml
// name: Release
// on:
// push:
// branches: [main, beta]
// jobs:
// release:
// runs-on: ubuntu-latest
// permissions:
// contents: write
// issues: write
// pull-requests: write
// id-token: write
// steps:
// - uses: actions/checkout@v3
// with:
// fetch-depth: 0
// - uses: actions/setup-node@v3
// with:
// node-version: 20
// - run: npm ci
// - run: npm test
// - run: npx semantic-release
// env:
// GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
// NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
// Example commits that trigger releases:
// feat: add user authentication -> minor bump (1.0.0 -> 1.1.0)
// fix: resolve memory leak in parser -> patch bump (1.1.0 -> 1.1.1)
// feat!: change API response format -> major bump (1.1.1 -> 2.0.0)
// docs: update README -> no release (unless custom releaseRules)
// chore: update dependencies -> no releaseOpen source library maintenance: Maintainers use semantic-release to publish new versions immediately after merging pull requests. When a contributor's fix gets merged, CI automatically publishes a patch release with generated release notes, eliminating the delay between code merge and npm availability.
Microservice deployments: Teams managing dozens of internal npm packages configure semantic-release to publish updated services to a private registry. Each service repository has its own configuration, ensuring version numbers reflect actual changes and deployment logs are automatically generated from commit history.
Monorepo package management: Combined with tools like Lerna or Nx, semantic-release analyzes commits per package to determine which workspace packages need new releases. A single CI run can publish multiple independent packages with correctly calculated version bumps based on their individual change history.
Pre-release channels: Development teams maintain multiple release channels (stable, beta, alpha) by configuring branch-specific settings. Commits to a beta branch automatically publish with the beta dist-tag, while main branch commits publish to the latest tag, allowing users to opt into pre-release versions.
Enterprise compliance workflows: Organizations requiring audit trails configure semantic-release with the @semantic-release/git plugin to commit generated CHANGELOG.md files and package.json updates back to the repository, creating a complete history of what triggered each release and what changed.
npm install semantic-releasepnpm add semantic-releasebun add semantic-release