Semantic Versioning: A Contract for Your Code's Evolution
Semantic Versioning is a contract for your code. The MAJOR.MINOR.PATCH format signals if an update is a breaking change, a new feature, or a bug fix. It's vital for managing dependencies safely. The footgun: SemVer is meaningless without a defined public API.
Why it exists
To escape "dependency hell." In large systems, updating packages can be a nightmare. If dependency rules are too tight, you get version lock and can't upgrade. If they're too loose, you get version promiscuity, where you assume compatibility and things break unexpectedly. SemVer provides a clear, predictable path forward.
The mental model
Think of a version number as a public promise about compatibility. MAJOR.MINOR.PATCH isn't just a number; it's a contract. A MAJOR bump says "Warning: This update may break your code." A MINOR bump says "New features, but your old code is safe." A PATCH bump says "Same features, just working better."
How it works
First, you must declare a public API. A version number takes the form X.Y.Z (MAJOR.MINOR.PATCH). You increment the MAJOR version for incompatible API changes, resetting MINOR and PATCH to 0. You increment the MINOR version for backward-compatible new functionality, resetting PATCH to 0. You increment the PATCH version for backward-compatible bug fixes. Pre-release versions (e.g., 1.0.0-beta) can be denoted by appending a hyphen.
When to use it
Use SemVer anytime you release software that other systems or developers depend on. This is essential for public npm packages, internal company libraries, microservices APIs, and design system component libraries. It allows consumers to automate updates safely, for instance by accepting all patch-level changes but requiring manual review for minor or major ones.
When not to use it
SemVer's strict rules don't apply before version 1.0.0. During initial development (versions 0.y.z), the API is considered unstable and anything may change at any time. The public API is not considered stable until the 1.0.0 release. For monolithic applications with no external consumers, its value is diminished.
One canonical example
A component library is at version 2.4.1. To fix a rendering bug that doesn't alter its API, the team releases 2.4.2 (PATCH). To add a new, optional iconPosition prop, they release 2.5.0 (MINOR). To rename an existing prop from label to text, which is a breaking change for anyone using the component, they must release 3.0.0 (MAJOR).
Interview question
A library updates from version 1.2.3 to 2.0.0. What does this change primarily signal to users?
- a.New features have been added that are backward-compatible.
- b.Existing code using the library might break and require modifications.Correct
- c.Only minor bug fixes have been applied to the library.
- d.The library has been completely rewritten internally.
Why? this is the answer
A MAJOR version increment (from 1.x.x to 2.0.0) signals incompatible API changes, meaning existing code relying on the previous API may break. New backward-compatible features are MINOR changes, and bug fixes are PATCH changes.
Just read this? Test yourself on what you have been reading.
Read the original → semver.org
- #versioning
- #api
- #dependencies
- #package management
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on versioning — each one lists the topics its interview covers.
See open roles