Skip to main content
DevBench
All articles
devtoolsjavascriptreference

Semantic Versioning (SemVer) Explained: Major, Minor, Patch

June 27, 20265 min read

If you have ever run npm install and seen a dependency jump from 2.3.1 to 3.0.0 and break everything, you have experienced a SemVer violation. Semantic versioning is a contract between package maintainers and their users — when followed correctly, version numbers communicate intent, not just change.

The format: MAJOR.MINOR.PATCH

A SemVer version has exactly three dot-separated numeric components:

ComponentWhen to incrementExample bump
MAJORBreaking changes — existing code will need updating2.4.1 → 3.0.0
MINORNew backward-compatible features2.3.1 → 2.4.0
PATCHBackward-compatible bug fixes2.3.1 → 2.3.2

When you increment MAJOR, reset MINOR and PATCH to 0. When you increment MINOR, reset PATCH to 0.

What counts as a breaking change?

A change is breaking if existing consumers of the public API need to change their code to keep working:

  • Removing a function, method, class, or exported value
  • Renaming a public API (even a typo fix)
  • Changing a function's signature (parameter types, order, or return type)
  • Changing default behaviour in a way that alters existing results
  • Raising the minimum Node.js / runtime version requirement

Adding new optional parameters, adding new exports, or fixing a bug without changing the interface are not breaking changes.

Pre-release versions

Pre-release identifiers follow the patch number with a hyphen:

VersionMeaning
1.0.0-alpha.1Early unstable release, no API guarantees
1.0.0-beta.2Feature-complete but potentially buggy
1.0.0-rc.1Release candidate — API locked, final testing

Pre-release versions have lower precedence than the release: 1.0.0-rc.1 < 1.0.0. They are not installed by npm unless you explicitly request them or use @next / @beta dist-tags.

npm version range operators

npm's package.json uses a range syntax to specify which versions are acceptable:

OperatorMeaningExampleInstalls
^Compatible — same MAJOR, any higher MINOR/PATCH^2.3.1>=2.3.1 <3.0.0
~Approximately — same MAJOR.MINOR, any higher PATCH~2.3.1>=2.3.1 <2.4.0
>=2.0.0 <3.0.0Explicit range>=2.0.0 <3.0.0Any v2.x
2.3.1Exact version (pinned)2.3.1Exactly 2.3.1
*Any version*Latest

^ is the npm default and usually the right choice for application dependencies. Use ~ (or exact pinning) for critical dependencies where unexpected MINOR changes could cause issues.

Version 0.x — special case

When MAJOR is 0 (e.g. 0.4.2), SemVer specifies that the API is not yet stable. Any version bump may be breaking. Treat each 0.x release like a MAJOR bump. The ^ operator reflects this: ^0.4.2 only allows >=0.4.2 <0.5.0, not 0.5.x.

Checking compatibility

# See what version npm would install for a range
npm info react@"^18.0.0" version

# Check if two versions are compatible
npx semver -r "^2.3.1" 2.4.0    # exits 0 (match)
npx semver -r "^2.3.1" 3.0.0    # exits 1 (no match)

Try it yourself

Use the free browser-based SemVer Comparator on DevBench — no signup, runs entirely in your browser.

Open SemVer Comparator