What Is Semantic Versioning? SemVer Explained With Examples

By Md Faizan

Published On:

Follow Us
Three stacked software release cards showing version numbers 1.0, 2.0 and 3.0 on a developer's desk

Version numbers look like decoration until an “upgrade” breaks your project and you discover the number was trying to warn you. Semantic Versioning — SemVer for short — is the widely used convention that makes a version number a promise: from 2.4.1 alone, you can tell what kind of change to expect. This guide explains the rules, when to bump each number, and the edge cases teams argue about.

SemVer pairs naturally with a changelog: the version tells readers how big a change is, and the changelog tells them exactly what it was.

The format: MAJOR.MINOR.PATCH

A SemVer version is three numbers separated by dots:

MAJOR.MINOR.PATCH — for example, 3.11.2

  • PATCH (3.11.2 → 3.11.3): backward-compatible bug fixes only. Upgrading should be safe without reading anything.
  • MINOR (3.11.3 → 3.12.0): new functionality added in a backward-compatible way. Existing behavior keeps working; the PATCH number resets to 0.
  • MAJOR (3.12.0 → 4.0.0): incompatible changes — anything that can break existing users: removed features, renamed or changed interfaces, new requirements. MINOR and PATCH both reset to 0.

That is the whole core spec, and you can apply it today: before every release, ask “could this break someone who uses the documented, public behavior?” If yes, it’s a major bump. If it only adds, it’s minor. If it only fixes, it’s patch.

What counts as “breaking”?

A change is breaking if a user following your documented public API or behavior would have to change something on their side after upgrading. Removing a function: breaking. Changing what a function returns: breaking. Raising the minimum runtime version: breaking. Fixing a bug so the output now matches the documentation: technically a behavior change, but SemVer counts documented behavior as the contract — this is famously the judgment call, and the honest move is to note it prominently in the changelog either way.

Internal changes don’t count. Refactoring, performance work and new tests are invisible to users, so on their own they justify at most a patch release.

Versions before 1.0.0

Software under initial development starts at 0.1.0. In the 0.x range, anything may change at any time — the convention is that a minor bump (0.3.0 → 0.4.0) may carry breaking changes, and patch bumps (0.4.0 → 0.4.1) stay fix-only. Release 1.0.0 when you are ready to declare a stable public API that you will protect with the full rules. That declaration is the point of 1.0.0 — not a feature count, not a marketing milestone.

Pre-releases and build metadata

Two suffixes extend the format:

  • Pre-release: a hyphen and identifiers, as in 2.0.0-alpha.1 or 2.0.0-rc.2. A pre-release has lower precedence than the normal version — 2.0.0-alpha comes before 2.0.0 — and signals “not finished; the API may still move.” Use it for alphas, betas and release candidates your users can test.
  • Build metadata: a plus sign, as in 1.4.2+build.57. Metadata is ignored when comparing versions; it records build details (commit, build number) without changing precedence.

Worked examples

  • A library fixes a crash when parsing empty files: 1.8.4 → 1.8.5 (patch).
  • The same library adds an optional export feature nobody is forced to use: 1.8.5 → 1.9.0 (minor).
  • It drops support for an old runtime version and removes two deprecated functions: 1.9.0 → 2.0.0 (major) — even if the new code is smaller than the old.
  • A brand-new internal tool, first shared build: 0.1.0.

SemVer and your changelog

Version numbers and changelogs do different jobs. SemVer answers “how careful should I be?” before an upgrade; the changelog answers “what exactly changed?” Commit discipline feeds both — teams that write good commit messages find release notes and version decisions much easier, because the history already separates fixes from features from breaking changes.

Common mistakes

  1. Bumping major for every release. If 7.0 follows 6.0 within weeks, users stop believing the signal and start pinning versions or skipping upgrades entirely.
  2. Hiding a breaking change in a minor release because the change “felt small.” Size isn’t the test — compatibility is.
  3. Using version numbers as marketing. “Version 2026!” may look fresh, but it tells an upgrader nothing about risk.
  4. Never reaching 1.0.0 on a mature, widely used project. Perpetual 0.x tells serious users the API is unstable whether it is or not.
  5. Forgetting to reset the lower numbers. 1.9.3 → 1.10.0, not 1.10.3; and a major bump resets both: 1.10.3 → 2.0.0.

Frequently asked questions

Is Semantic Versioning an official standard?
It is a specification (published at semver.org) maintained as an open convention rather than by a standards body. Its authority comes from adoption — package ecosystems like npm build version rules directly on it.

Does SemVer apply to websites and apps, not just libraries?
The rules fit anything with users who depend on behavior: APIs, CLIs, apps with plugins or saved data formats. For a pure content website with no public API, version numbers matter less — but an internal version habit still helps teams communicate change size.

What comes after 1.9.0 — 1.10.0 or 2.0.0?
1.10.0, unless the release contains a breaking change. Numbers are not decimal fractions; there is no rule that minor must stay a single digit.

How do I version a fix to an old major line?
Branch it: if 2.x is current but 1.9.2 needs a critical fix, release 1.9.3 from the 1.x branch. Maintaining older lines with patch releases is standard practice.

What about dates as versions (like 2026.11)?
That’s calendar versioning (CalVer), a legitimate different scheme used by projects like Ubuntu. It communicates freshness, not compatibility — choose it deliberately, not by accident, and don’t mix the two signals in one number.

Bottom line

Semantic Versioning turns three numbers into a contract: patch means fixes, minor means additions, major means breakage. Follow it consistently and your users can upgrade with confidence instead of fear — and your version history becomes documentation in its own right.

Leave a Comment