
What Is Semantic Versioning (SemVer)? MAJOR.MINOR.PATCH, Explained
- VersionDude
- guides
- 7 min read
Semantic Versioning numbers releases as MAJOR.MINOR.PATCH so the version itself tells you what changed. What each part means, the reset rules, pre-release labels, and how npm ranges like ^1.2.3 rely on it.
Semantic Versioning, almost always shortened to SemVer, is a simple set of rules for numbering software releases so that the version number itself tells you what changed. Instead of a meaningless counter, a SemVer version is three numbers - MAJOR.MINOR.PATCH, like 2.4.1 - and each position has a defined meaning. Once you know the rules, you can look at a version bump and immediately understand whether an update is safe, adds features, or might break your code.
The three parts each answer a different question. MAJOR (the first number) increases when you make incompatible, breaking changes to the public API - upgrading might require you to change your own code. MINOR (the second) increases when you add new functionality in a backward-compatible way - new features you can adopt or ignore. PATCH (the third) increases for backward-compatible bug fixes - safe corrections that do not change how the software is used.
There are two mechanical rules that trip people up. When you increase MAJOR, you reset MINOR and PATCH to zero: after 1.4.2, a breaking change becomes 2.0.0, not 2.4.2. When you increase MINOR, you reset PATCH to zero: after 1.4.2, a new feature becomes 1.5.0. So the numbers to the right always restart when a number to their left goes up.
SemVer also has a special rule for early development. Any version starting with 0 - like 0.3.1 - is considered unstable, and the normal guarantees do not fully apply. During 0.x, the API can change at any time, so treat those releases with caution. The jump to 1.0.0 is a deliberate signal: it means the author is committing to a stable public API and to following the SemVer rules from then on.
Beyond the three core numbers, SemVer supports pre-release and build labels. A pre-release version adds a hyphen and an identifier, such as 1.0.0-alpha, 1.0.0-beta.2 or 1.0.0-rc.1, and it has lower precedence than the final release - so 1.0.0-rc.1 comes before 1.0.0. Build metadata can be added after a plus sign, like 1.0.0+20260715, but it is ignored when comparing versions. This lets teams ship test builds without pretending they are finished releases.
The reason all of this matters is dependency management. When your project depends on a library, you rarely pin one exact version forever; you allow a range. Package managers use SemVer to make those ranges safe. In npm, for example, a caret range like ^1.2.3 means any version from 1.2.3 up to but not including 2.0.0 - all the backward-compatible updates, none of the breaking ones. A tilde range like ~1.2.3 is tighter, allowing patch updates up to but not including 1.3.0.
Those ranges only work because everyone agrees on what a version bump means. If a library ships a breaking change but only increments PATCH, it can silently break every project that trusted the range. That is the social contract at the heart of SemVer: the number is a promise about compatibility, and honouring it is what keeps the whole ecosystem of automatic updates from falling apart.
SemVer is defined by a short, readable specification at semver.org, and it is the scheme used by npm, Cargo, and countless other package registries and tools. It is not the only way to version software - some projects use calendar versioning (like 2026.07) or their own scheme - but SemVer is the most widely understood, and knowing it makes reading changelogs and dependency ranges far easier.
The practical takeaway: read a version as a sentence. A jump in the first number says stop and check for breaking changes before upgrading. A jump in the second says there are new features but your existing code is safe. A jump in the third says it is a safe bug fix. That single habit - reading the position that changed - turns an opaque number into a clear message about risk.


