Semantic Versioning — commonly called SemVer, a specification with a widely adopted three-part MAJOR.MINOR.PATCH numbering format — exists to solve a specific communication problem: letting a piece of software's users understand, from the version number alone, what kind of change happened between two releases, without reading a full changelog first. The specification's actual promise is narrower and more specific than “bigger number means newer version,” and understanding the specific promise is what makes the numbering genuinely useful rather than just decorative. The canonical rules are published in the Semantic Versioning specification.
What each number is specifically supposed to mean
Under the specification, a PATCH increment (the last number) signals a backward-compatible bug fix — nothing about how callers use the software should need to change to adopt it safely. A MINOR increment (the middle number) signals new, backward-compatible functionality — existing callers remain unaffected, but new capability is available for those who want it. A MAJOR increment (the first number) signals a breaking change — something about the software's behavior or interface has changed in a way that could require adjustments in code that depends on it. The entire value of the scheme rests on this being a reliable, honest signal: a caller deciding whether to safely accept an automatic update should be able to trust a PATCH or MINOR bump not to break their code, without needing to read the full changelog to verify it. Timing itself communicates expectations, a concept explored further in the source.
This is why SemVer is, underneath the numbering convention, really a specific promise about API design discipline, connecting directly to the API-design guide discussed elsewhere on this shelf: correctly applying SemVer requires the maintainer to correctly and honestly classify every single change according to whether it's actually backward-compatible, which depends on a clear, consistent understanding of what the public API's actual surface and guarantees are in the first place.
Why version numbers are so often wrong in practice
In practice, SemVer compliance is inconsistently applied across the software ecosystem, and the most common failure is an under-classified breaking change — released as a MINOR or even PATCH bump when it actually changes behavior in a way that breaks some callers, usually because the maintainer didn't realize a particular change was breaking for some real, if less obvious, use case. This is a genuinely difficult classification problem for any API with a large, diverse set of callers using it in ways the maintainer may not have anticipated, and it's a significant reason experienced users of a dependency often remain cautious about automatically accepting even nominally non-breaking updates, despite the specification's promise.
- A version number under SemVer is a specific, checkable promise, not just an indicator of recency — a PATCH or MINOR bump specifically promises backward compatibility.
- Correctly classifying a change as breaking or non-breaking requires a clear sense of what the public API's actual guarantees are — an ambiguous or undocumented API surface makes honest SemVer compliance genuinely difficult.
- Under-classified breaking changes (a real breaking change released as a MINOR or PATCH bump) are a common, well-documented failure mode — often unintentional, from a maintainer not anticipating every real use case.
- A changelog remains valuable alongside a version number, specifically for the cases where the version number's classification might be wrong, or where the specific nature of a change matters even if it's correctly classified as non-breaking.
Why the convention is still worth following, imperfections and all
Despite inconsistent real-world compliance, SemVer remains valuable specifically because it establishes a shared, widely understood expectation — even an imperfectly followed convention gives users a meaningfully better default expectation than an arbitrary or inconsistent versioning scheme would, and deviations from the convention (an unexpected breaking change in a MINOR release) are at least identifiable as deviations from a known standard, which makes them discussable and fixable, rather than simply being unpredictable in a system with no shared convention to violate in the first place.
Understood this way, semantic versioning is less a purely mechanical numbering rule and more a discipline that depends on the API design clarity discussed elsewhere on this shelf — a well-defined, consistently designed public surface is what actually makes honest, reliable SemVer classification possible in the first place.