Semantic Versioning
Semantic versioning encodes compatibility in a three-part version number, so consumers can tell a breaking change from a feature or a bug fix before upgrading.
Definition
Semantic versioning is a versioning convention of MAJOR.MINOR.PATCH, where MAJOR increments for incompatible API changes, MINOR for backward-compatible features, and PATCH for backward-compatible fixes, with prerelease and build metadata as optional suffixes.
Context and scope
It is used by libraries, SDKs, and internal packages whose consumers need to reason about upgrade risk and automate dependency updates safely.
Common misconceptions
- Semver guarantees compatibility — it is a promise by maintainers, not a proof; mistakes and edge cases still happen.
- 0.x versions are stable — semver treats initial development as unstable, where minor releases may break.
- A major bump always breaks you — it signals possible breakage in the public API, not that your usage is affected.
Anti-patterns
- Shipping a breaking change in a patch release to avoid a major version bump
- Bumping the major version for every change so the number loses meaning
- Treating internal, unpublished packages as if semver ranges were a safety net
Related concepts
Related examples
Authoritative source
Three numbers, one promise
Semantic versioning assigns meaning to each position. MAJOR changes when the public API breaks, MINOR when functionality is added compatibly, PATCH when a bug is fixed without changing the contract. Prerelease identifiers such as 2.0.0-rc.1 sort before the final release, and build metadata after a plus sign is ignored for precedence. The number is a communication contract between maintainer and consumer.
1.4.2 -> 1.4.3 patch: bug fix, safe to adopt
1.4.2 -> 1.5.0 minor: new feature, backward compatible
1.4.2 -> 2.0.0 major: breaking change, read the migration guide
When to use it
Use semver for any package other people depend on, including internal shared libraries. Pair it with a changelog and a deprecation policy, because the number alone does not explain what changed. Applications that are never consumed as a dependency gain less from strict semver, though release notes still benefit from the same discipline.
Trade-offs
Semver only works if maintainers are honest and consumers understand it. Ranges like ^1.2.0 assume the maintainer never breaks compatibility in a minor release, an assumption that fails often enough that lockfiles are still required. Strictness also adds release overhead; deciding what counts as public API is a design decision, not a formatting one.
Example and misconceptions
A UI library adds an optional prop: minor bump, and apps on ^3.4.0 receive it automatically. It later renames a prop: major bump, and the changelog shows a codemod. The misconception that semver prevents breakage is dangerous; it only labels risk. Related concepts: dependency pinning, backward compatibility, and CI/CD.