Skip to content

/glossary/semver/semantic-versioning

What is semantic versioning (SemVer)?

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
SemVer
versions
SemVer 2.0.0
os
any

Semantic versioning (SemVer) is a convention for version numbers of the form MAJOR.MINOR.PATCH, such as 2.4.1. Increment MAJOR for changes that break the public API, MINOR for new features that stay backward compatible, and PATCH for backward compatible bug fixes. Package managers rely on it: a range like ^2.4.1 accepts any later 2.x release because those must not break code written for 2.4.1.

The rules in practice

The semver package (the implementation npm uses) shows how versions are incremented and ordered:

bash
npm init -y >/dev/null
npm install --silent --no-audit --no-fund semver@7 >/dev/null 2>&1
cat > rules.js <<'EOF'
const semver = require("semver");
console.log("patch:", semver.inc("2.4.1", "patch"));
console.log("minor:", semver.inc("2.4.1", "minor"));
console.log("major:", semver.inc("2.4.1", "major"));
console.log("pre:  ", semver.inc("2.4.1", "premajor", "rc"));
const list = ["1.0.0", "1.0.0-rc.1", "1.0.0-alpha", "1.0.0-alpha.10", "1.0.0-alpha.2", "0.9.12", "1.0.0+build.5"];
console.log("sorted:", semver.sort(list).join("  "));
console.log("valid 1.2:", semver.valid("1.2"), "| valid v1.2.3:", semver.valid("v1.2.3"));
EOF
node rules.js

Output

patch: 2.4.2
minor: 2.5.0
major: 3.0.0
pre:   3.0.0-rc.0
sorted: 0.9.12  1.0.0-alpha  1.0.0-alpha.2  1.0.0-alpha.10  1.0.0-rc.1  1.0.0  1.0.0+build.5
valid 1.2: null | valid v1.2.3: 1.2.3

Parts of a version

PartExampleRule
MAJOR2.x.xIncompatible API change; resets MINOR and PATCH to 0
MINORx.4.xNew backward compatible functionality; resets PATCH to 0
PATCHx.x.1Backward compatible bug fix
Pre-release1.0.0-rc.1After a hyphen; sorts before the release 1.0.0
Build metadata1.0.0+build.5After a plus; ignored when comparing precedence

Pre-release identifiers are compared piece by piece: numeric parts numerically (alpha.2 < alpha.10), text parts alphabetically (alpha < rc).

Which number to bump

The public API is whatever you document as such: functions, command-line flags, configuration keys, HTTP endpoints, file formats. SemVer only works if you write it down, because "breaking" is measured against it.

ChangeBumpWhy
Remove or rename a public function, flag or optionMAJORExisting callers stop working
Change a default or a return type in an incompatible wayMAJORSame call, different result
Drop support for a runtime version (for example an old Node.js)MAJOR (usual practice)Users on that runtime can no longer upgrade
Add a new function or an optional parameterMINOROld code keeps working, new code can use it
Mark something as deprecatedMINORBehaviour is unchanged, only a warning is added
Fix a bug without changing the documented behaviourPATCHCode that relied on the documented behaviour is unaffected
Change documentation, tests or internal refactoring onlyPATCH or noneNothing observable changes

Once a version is published, its contents must not change: any fix, however small, is a new version.

Version 0.y.z

Major version zero is for initial development: anything may change at any time, and the public API is not considered stable. Many tools treat ^0.4.1 as >=0.4.1 <0.5.0 for that reason. Release 1.0.0 once other people depend on the API.

FAQ

Is v1.2.3 a semantic version?

Strictly, no: the spec defines the version as 1.2.3, and the semver.org FAQ calls the v prefix a common convention for tags. Tools like node-semver strip it (valid('v1.2.3') returns 1.2.3).

What if I released a breaking change as a minor version by mistake?

Do not change the published release. Publish a new minor that restores compatibility, then ship the breaking change in the next major; the semver.org FAQ gives the same advice.

How should I deprecate something under SemVer?

Mark it deprecated in a minor release, with documentation telling users what to use instead, and remove it only in a later major release.

Sources