SemVer (Semantic Versioning) is a specification by Tom Preston-Werner
(GitHub co-founder). Version format: MAJOR.MINOR.PATCH.
What each number means
- PATCH (1.4.2): backward-compatible bug fixes. Upgrading from 1.4.1 to 1.4.2 fixes a bug and breaks nothing.
- MINOR (1.4.0): new backward-compatible functionality. Existing code continues to work; something new and optional has appeared.
- MAJOR (1.0.0): breaking changes. Something is incompatible; an upgrade requires code migration.
When a higher component increases, the lower ones reset to zero:
1.4.2 → 1.4.3 (patch)
1.4.2 → 1.5.0 (minor)
1.4.2 → 2.0.0 (major)
Additional labels
1.4.2-beta.1,1.4.2-rc.3: pre-release. Sorts before1.4.2without a suffix.1.4.2+20260527.git7c8a1: build metadata. Ignored in comparisons.
Sort order: 1.4.2-alpha.1 < 1.4.2-beta.1 < 1.4.2-rc.1 <
1.4.2 < 1.4.3.
0.x.y versions
While major is 0, SemVer does not apply strictly. The version is
"unstable": breaking changes may appear even in minor bumps. This is the
"promise to make no promises". Many projects stay at 0.x for years
because they do not want to take on SemVer obligations.
Moving to 1.0.0 means: "the API is public; I commit to SemVer." It does
not mean "production-ready". It means backward compatibility is now policy.
Connection to Conventional Commits
With conventional-commits, SemVer is selected automatically:
| Commits since last release | New version |
|---|---|
Only fix: / chore: / docs: | PATCH |
At least one feat: (no BREAKING) | MINOR |
At least one BREAKING CHANGE: or ! | MAJOR |
Tools such as semantic-release, release-please, and standard-version
do this automatically: they read the commits, compute the next version,
create a git tag, and update CHANGELOG.md.
Common mistakes
- "My patch broke someone's code." If a patch breaks a user, it is not a patch; it is a major. A patch must be backward-compatible.
- "I rewrote the internals, so it is PATCH." If the external behavior did not change: yes, PATCH. If it did change: minor or major. Internal rewrites alone do not determine the bump level.
- "I use
^in package.json."^1.4.2means "any1.x.y≥ 1.4.2". This works because SemVer promises compatibility within a major. If the library author violates SemVer,^will let you down.
Pitfalls
- Pre-1.0 is awkward for users. If people already depend on your
library, moving to 1.0 gives them guarantees. Staying at
0.xfor decades is an anti-pattern. - Major bumps are expensive. Users must migrate. If your library has an active ecosystem, plan deprecation periods and give people a year to transition.
- CalVer is an alternative to SemVer. Format:
2026.05.0(year.month.release). Used by Ubuntu, pip, and JetBrains. No compatibility promises; it is simply a timestamp. Do not confuse it with SemVer.