Migrate in ~15 minutes
- Remove
semantic-releaseconfig frompackage.json - Install semrel
- Run
semrel release --dry-run— the output should match your previous releases
The release automation market has several established tools. This page gives you the information to choose the right one — or migrate from what you have.
| semrel | semantic-release | goreleaser | release-please | release-it | changesets | |
|---|---|---|---|---|---|---|
| Runtime | None | Node.js + npm | None | Node.js + npm | Node.js + npm | Node.js + npm |
| Install size | ~12 MB | ~350 MB | ~45 MB | ~300 MB | ~200 MB | ~150 MB |
| Air-gap ready | ✅ Native | ❌ | ✅ | ❌ | ❌ | ❌ |
| Cold-start overhead | ~0 ms | 30–60 s (Node setup) | ~0 ms | 30–60 s | 30–60 s | 30–60 s |
| semrel | semantic-release | goreleaser | release-please | release-it | changesets | |
|---|---|---|---|---|---|---|
| Auto SemVer from commits | ✅ | ✅ | ❌ tag-based | ✅ | ✅ | ❌ manual |
| Conventional Commits | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| Scope-based bump rules | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
| Monorepo support | ✅ Free | ✅ | ✅ | ✅ | ✅ | ✅ |
| Plugin language | Any binary | JS only | Go (built-in) | Hardcoded | JS only | JS only |
| semrel | semantic-release | goreleaser | release-please | release-it | changesets | |
|---|---|---|---|---|---|---|
| Signed releases (Cosign) | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| SBOM (CycloneDX/SPDX) | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| SLSA provenance | ✅ Level 1 | ❌ | ✅ | ❌ | ❌ | ❌ |
| npm supply-chain exposure | None | High (400+ deps) | None | Medium | Medium | Medium |
| Air-gapped pipelines | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ |
| semrel | semantic-release | goreleaser | release-please | release-it | changesets | |
|---|---|---|---|---|---|---|
| License | Apache 2.0 | MIT | MIT / Pro paid | Apache 2.0 | MIT | MIT |
| Free monorepo | ✅ | ✅ | ✅ OSS | ✅ | ✅ | ✅ |
| Enterprise features | Free | Free | $3,300/yr | Free | Free | Free |
| GitHub Stars | — | ~23.7k | ~15.6k | ~7.1k | ~12.2k | ~8.4k |
semantic-release is the pioneer of commit-driven semantic versioning and is widely used across thousands of enterprise pipelines. semrel was built to replicate its behaviour without the runtime cost.
Integrating semantic-release into a Go, Rust, or C++ pipeline requires:
# Added to every pipeline job:actions/setup-node@v4 # 30-60 seconds on cold runnersnpm install -g semantic-release # 28+ direct deps, 400+ transitiveOn a minimal Alpine Linux runner or Docker-in-Docker environment this means pulling a full Node.js runtime into a container that otherwise contains only a Go toolchain.
semrel replaces the entire block with:
curl -L https://github.com/SemRels/semrel/releases/latest/download/semrel_linux_amd64.tar.gz | tar -xz./semrel releasesemantic-release is known to time out in repositories with many tags and branches. At 460 tags and 65 branches, reported execution times exceed 35 minutes due to sequential Git history traversal and API calls.
semrel is compiled Go — it traverses git log and queries forge APIs concurrently. Typical execution time on the same repository profile: under 90 seconds.
semantic-release installs 28 direct npm dependencies and hundreds of transitive packages on every pipeline run. The npm ecosystem has been the target of repeated supply-chain attacks.
semrel is a single statically compiled binary. There are no node_modules, no runtime package resolution, and no transitive dependency attack surface.
Both semrel and semantic-release support routing commits to bump levels by scope. semrel’s rules array accepts an optional scope field — including scope: false to match only commits with no scope at all:
# semrel (.semrel.yaml)rules: - type: deps scope: major bump: major - type: deps scope: minor bump: minor - type: deps scope: patch bump: patch - type: feat bump: minor// semantic-release (package.json){ "releaseRules": [ { "type": "deps", "scope": "major", "release": "major" }, { "type": "deps", "scope": "minor", "release": "minor" } ]}Migrate in ~15 minutes
semantic-release config from package.jsonsemrel release --dry-run — the output should match your previous releasesEquivalent config mapping:
| semantic-release | semrel equivalent |
|---|---|
@semantic-release/github | provider-github plugin |
@semantic-release/gitlab | provider-gitlab plugin |
@semantic-release/changelog | generator-changelog-md plugin |
@semantic-release/git | built-in git commit step |
@semantic-release/npm | updater-npm plugin |
@semantic-release/exec | any shell script via hook-* |
releaseRules[].scope | rules[].scope (string or false) |
For a detailed step-by-step migration guide, see From semantic-release to semrel.
goreleaser and semrel solve different problems and are commonly used together.
| Concern | semrel | goreleaser |
|---|---|---|
| What version is this release? | ✅ Calculates from commits | ❌ You provide the tag |
| Compile for linux/arm64, darwin/amd64, etc. | ❌ Not its job | ✅ Core feature |
| Create GitHub/GitLab release with assets | ✅ Via provider plugins | ✅ Core feature |
| Generate changelog | ✅ Via generator plugins | Partial (via templates) |
| Publish to Docker, Homebrew, npm, PyPI | ✅ Via updater + packager + publisher plugins | ✅ Core feature |
| Monorepo versioning | ✅ Free | ✅ Free (OSS plan) |
Recommended combined workflow:
# GitHub Actions- name: Compute next version run: semrel release --dry-run --output json > semrel-output.json
- name: Build & distribute uses: goreleaser/goreleaser-action@v6 with: args: release env: GORELEASER_CURRENT_TAG: ${{ fromJson(steps.prev.outputs.json).nextVersion }}For a step-by-step migration guide, see From goreleaser to semrel.
release-please (by Google) uses a pull-request-first model. Instead of releasing on every push, it:
| Concern | semrel | release-please |
|---|---|---|
| Fully automated (no PR gate) | ✅ | ❌ PR required |
| Conventional Commits | ✅ | ✅ |
| Supports GitLab / Gitea | ✅ | ❌ GitHub only |
| Plugin extensibility | ✅ Any binary | ❌ Hardcoded updaters |
| Node.js dependency | ❌ None | ✅ Required |
Choose release-please if your team requires human sign-off before every release. Choose semrel for fully hands-off CI releases or non-GitHub forges.
For a step-by-step migration guide, see From release-please to semrel.
release-it is a popular JavaScript-based release tool with an interactive CLI mode. It supports Conventional Commits, changelogs, npm publishing, and GitHub releases.
| Concern | semrel | release-it |
|---|---|---|
| Runtime | None | Node.js + npm |
| Conventional Commits auto-bump | ✅ | ✅ |
| Scope-based bump rules | ✅ | ❌ |
| Interactive release wizard | ❌ | ✅ |
| Air-gap / offline pipelines | ✅ | ❌ |
| Supply-chain exposure | None | Medium (npm deps) |
| GitLab / Gitea / Bitbucket | ✅ | Partial (GitLab plugin) |
| Plugin language | Any binary | JS only |
release-it is a good fit for JavaScript/TypeScript projects that already use Node.js in CI and want an interactive experience. Choose semrel for any non-JS tech stack, air-gapped environments, or when supply-chain hardening matters.
changesets is JavaScript/TypeScript-centric and requires developers to manually create changeset files describing their changes. It does not read Conventional Commits automatically.
| Concern | semrel | changesets |
|---|---|---|
| Auto-bump from commits | ✅ | ❌ Manual changeset files |
| Conventional Commits | ✅ | ❌ |
| Developer overhead | None | High (per-PR changeeset) |
| Monorepo support | ✅ | ✅ |
| Non-JS projects | ✅ | ❌ Designed for JS/TS |
| Runtime | None | Node.js + npm |
Choose semrel if you want zero developer overhead — just write Conventional Commits and CI handles the rest. changesets suits large JS monorepos where fine-grained human control over each package’s version bump is preferred over automation.
Do you need zero Node.js in your pipeline? → Yes → semrel ✅ → No → any tool works
Do you need air-gap / fully offline CI? → Yes → semrel ✅ → No → any tool works
Do you need automated versioning from commit messages? → Yes → semrel, semantic-release, or release-it → No → goreleaser (tag-based)
Do you need scope-based bump rules (e.g. deps(major))? → Yes → semrel or semantic-release ✅ → No → any tool works
Do you need cross-platform Go binary compilation? → Yes → goreleaser (can combine with semrel) → No → semrel is sufficient
Do you want human PR approval before release? → Yes → release-please → No → semrel ✅
Is your project exclusively JavaScript/TypeScript? → Yes, and you want interactive releases → release-it → Yes, and you want manual version control → changesets → No → semrel ✅
Do you need GitLab, Gitea, or Bitbucket support? → Yes → semrel ✅ → No → any tool works