A version number that’s just an incrementing counter tells a dependent nothing about what actually changed. Semantic versioning exists to make version numbers carry real, specific information instead.
The major.minor.patch format
Semantic versioning (SemVer) defines a version number as three components — MAJOR.MINOR.PATCH — each with a specific, agreed meaning, laid out in the official semantic versioning specification:
- MAJOR increments when a change breaks backward compatibility — existing code depending on the previous version may not work correctly with the new one without modification.
- MINOR increments when functionality is added in a backward-compatible way — existing code continues to work unchanged, with new capability available if the dependent chooses to use it.
- PATCH increments for backward-compatible bug fixes — behavior that was supposed to work a certain way now actually does, with no intentional change to the public interface.
Why this matters more than it might seem
The entire value of this scheme depends on it being followed accurately, because it lets automated tooling and human dependents make a decision without reading every line of a changelog: a patch release should be safe to take automatically, a minor release should be safe but worth a glance at what’s new, and a major release needs actual review before upgrading, since something may have intentionally broken. Package managers across essentially every modern ecosystem rely on this convention to let developers specify acceptable version ranges for their dependencies — accepting patch and minor updates automatically, for instance, while requiring a deliberate action to move to a new major version. Whether a given release is even allowed to reach consumers automatically is often itself governed by a deployment stage gate requiring the right checks to pass first.
What breaks when SemVer isn’t followed accurately
A backward-incompatible change released as a minor or patch version, rather than a major one, defeats the entire point of the scheme: dependents who configured their tooling to accept minor and patch updates automatically, trusting the version number’s promise, get a breaking change they didn’t expect and weren’t warned about. This is a common, real source of dependency-related outages, and it’s a direct violation of the implicit contract SemVer establishes — not a minor technicality, since the entire ecosystem of automated dependency management tooling is built on the assumption that the promise is actually kept.
How this connects to immutable, versioned artifacts
Semantic versioning is a natural complement to the immutable build artifacts discussed in Build Once, Deploy Everywhere: a specific, immutable artifact tagged with a specific SemVer version gives every consumer of that artifact a precise, meaningful way to reason about what they’re depending on, and whether a newer version is safe to adopt — version identifiers that don’t carry this kind of meaning make that reasoning considerably harder, forcing a dependent to actually read a changelog (or worse, the diff itself) for every single update, regardless of scale.
Pre-1.0 versions: a deliberate exception
The specification carves out an explicit exception for version 0.y.z: everything before 1.0.0 is considered initial development, where the public interface is not yet considered stable and breaking changes may happen in minor or patch releases without violating the scheme. This is worth knowing specifically because it means depending on a pre-1.0 package carries meaningfully different risk than depending on a post-1.0 one — the version number itself is signaling that the normal guarantees don’t fully apply yet.
Key takeaway
Semantic versioning gives a version number real, specific meaning — major for breaking changes, minor for safe additions, patch for safe fixes — which is what lets both humans and automated tooling make informed decisions about whether to upgrade a dependency without inspecting every change individually. That system only works as long as the convention is actually followed accurately; a breaking change mislabeled as a minor or patch release undermines the trust the entire scheme depends on.
This article explains a general versioning convention; adherence to it is a project-by-project practice, not something enforced automatically. See our disclaimer.