Semantic versioning is the convention for communicating the scope of changes to an API through its version number, and it’s both genuinely useful and a subject I’ve grown increasingly skeptical about over the years. Semantic versioning — semver — uses a MAJOR.MINOR.PATCH scheme where a major version bump signals breaking changes, a minor bump signals backward-compatible additions, and a patch signals backward-compatible fixes. The promise is that the version number itself tells consumers what to expect: a major version change means “this might break you, pay attention,” while a minor or patch change means “you can adopt this safely.” It’s a clean, communicative convention, and Google’s guidance on API versioning, which I wrote about in 2017, was built on this semantic approach. But the longer I’ve watched API versioning in practice, the more I’ve come to see versioning — even semantic versioning — as a coping mechanism for problems that better discipline could prevent.
The core value of semantic versioning is communication, and that’s worth acknowledging clearly. The whole point of semver is to make the version number meaningful — to encode, in the number itself, information about the compatibility implications of a change. This is genuinely valuable: a consumer looking at a version number should be able to infer whether updating is safe or risky. Google’s versioning guidance promoted exactly this clarity, using semantic versioning to communicate breaking versus non-breaking changes. The rules for extending your API with each version, which I wrote about in 2018, are about staying within the additive, backward-compatible changes that don’t require a major version bump — extending the API without breaking it. When semantic versioning works, it gives consumers a reliable signal about what each version change means for them, which is the entire reason versioning exists.
The path-versus-header debate is the most persistent technical argument in API versioning, and I’ve documented it with some amusement. The “correct” answer, by REST orthodoxy, is that versioning belongs in headers, not in the URL path — because the URL should identify the resource, not the version. But I wrote in 2018 about why versioning in the path is still the dominant pattern despite this — because path versioning (api.example.com/v2/…) is simply more practical, more visible, and easier for developers to work with than the theoretically-correct header approach. And in 2024 I wrote that 5 of the 7 top API providers do versioning “wrong” by putting it in the path — maybe wrong is right. This captures a recurring theme in my thinking: the theoretically-pure approach often loses to the practical one, and when the overwhelming majority of the best API providers do something the “wrong” way, maybe the orthodoxy is what’s wrong. Path versioning won because it works for developers, regardless of what REST purity demands.
The breaking-change dimension is where versioning connects to the real cost it’s trying to manage. Versioning exists fundamentally to manage breaking changes — the changes that would break existing consumers if deployed without warning. I wrote in 2022 about detecting breaking changes across API versions — the tooling that can automatically identify when a change between versions is breaking, which is essential to versioning correctly. And I wrote in 2024 about what breaking changes mean at the business level — not just the technical definition but the business reality of pricing changes, SLA changes, and terms changes that break the consumer relationship even when the technical interface stays stable. Semantic versioning is the convention for communicating about breaking changes, but the deeper work is avoiding unnecessary breaking changes in the first place through careful, additive, backward-compatible API evolution. The best versioning practice is the one that rarely needs a major version bump because the API evolves additively.
My increasingly skeptical view crystallized in 2025, when I wrote that API versioning is just an engineering coping mechanism amidst unrealistic business deadlines — and this is the most important thing I have to say about versioning. The provocative claim is that a lot of versioning, including the proliferation of major versions, isn’t a sign of healthy API evolution but a symptom of dysfunction: when business pressure forces teams to ship faster than they can design carefully, they version their way around the breaking changes that good design would have avoided. Versioning becomes the coping mechanism for the technical debt that unrealistic deadlines create. A new major version is often an admission that you couldn’t evolve the existing API gracefully — and while sometimes that’s genuinely necessary, often it’s the consequence of rushed design that didn’t think carefully enough about extensibility upfront. Semantic versioning communicates the breaking change honestly, which is good, but the need for the breaking change is frequently a failure that better discipline could have prevented.
The governance framing is where versioning becomes a manageable practice rather than an ad-hoc reaction, and it’s where I’ve landed most constructively. I wrote in 2024 about governance policies, rules, and guidance for managing the versioning of OpenAPI and APIs — because versioning, done well, is a governed practice with clear policies about when to version, how to communicate it, how long to support old versions, and how to deprecate them. The synthesis I’d offer is that semantic versioning is a genuinely useful communication convention — encoding the compatibility implications of changes into the version number is valuable, and consumers benefit from version numbers that mean something. But versioning is also frequently a coping mechanism, a symptom of the design dysfunction and deadline pressure that produces avoidable breaking changes. The mature practice uses semantic versioning to communicate honestly when changes do happen, governs versioning with clear policies, detects breaking changes automatically, evolves APIs additively to minimize the need for major versions, and recognizes that the best versioning is the versioning you rarely have to do because you designed for extensibility from the start. Semantic versioning is the honest way to communicate change, but the deeper goal is the careful, additive, well-governed API evolution that keeps the breaking changes — and therefore the major version bumps — to a minimum. Version when you must, communicate clearly when you do, and treat the frequent need to version as a signal that the design discipline upstream might need attention.
References
- Guidance On Versioning Your API From Google
- Rules For Extending Your API With Each Version
- Why Is API Versioning In The Path Still The Dominant Pattern
- Detecting Breaking Changes Across API Versions
- What Are Breaking Changes When It Comes To The Business Of APIs?
- API Governance Policies, Rules, And Guidance For Managing The Versioning Of OpenAPI And APIs
- 5 Of The 7 Top API Providers Do API Versioning Wrong, Maybe Wrong Is Right
- API Versioning Is Just An Engineering Coping Mechanism Amidst Unrealistic Business Deadlines