Not too long ago, version numbers were all ad hoc — everyone had a different way to do it. Now, and in large part thanks to the adoption by npm, most of the world has largely accepted and moved to Semantic Versioning. Semantic Versioning standardizes a tripartite version number x.y.z
where x
is the “major number,” y
is the “minor number,” and z
is the “patch number.” Because the version number has meaning, this allows you with any two version numbers to make one of three qualitative and semantic statements
When the major number (
x
inx.y.z
) changes it “represents a breaking change and potentially more features and bug fixes”Ergo, an upgrade of this sort can NOT be assumed to be compatible with your code base at all.
Or, when the major number remains static and the minor number (
y
inx.y.z
) changes it “represents more features and potentially bug fixes”Ergo, a higher minor number can be assumed to be compatible but can NOT be assumed to be free of security vulnerabilities nor to be free of additional bugs which may be introduced by the development of new features.
Or, when the major number and minor number remains static and the patch number (
z
inx.y.z
) changes it “represents solely bug fixes”Ergo, a higher patch number can GENERALLY be assumed to neither introduce an incompatibility nor additional bugs nor additional vulnerabilities.
Semantic Versioning has proven to be tremendously useful and it has been the status quo for a very long period of time.
Adopt semantic versioning by making the first public release of your software 1.0.0. Or increment the major number and from that point on, simply follow the convention above.
In practice; developing with Semantic Versioning
To think about Semantic Versioning more formally if any two different semantic versions are compared the result of the comparison is the change between the two versions and can be represented as an enumeration of these three outcomes
MAJOR: “represents a breaking change and potentially more features and bug fixes”
MINOR: “represents more features and potentially bug fixes”
PATCH: “represents solely bug fixes”
change = compare( semvarBefore, semvarAfter )
Where change
of type ENUM[MAJOR,MINOR,PATCH]
.
Further, knowing the semvarBefore
and the change
whether MAJOR
, MINOR
, PATCH
you can calculate the next valid semvarAfter.
This is done normally with a “bump” tool.
semvarAfter = bump( semvarBefore, change )
The bumper tool can be implemented simply:
When major changes: increment major, clear (set to zero) minor and patch
Or, when minor changes: retain major, increment minor, clear (set to zero) patch
Or, when patch changes: retain major and minor, increment patch
When using semantic versioning, a developer will
take the current version number
review the changes from that version until the point you wish to publish as a new version to decide which one of the statements above summarizes the magnitude of the changes, and
hand both the current version and the type of change or bump needed to the bumper
This would provide them their new version number.
Pre-release and build-metadata
There are two advanced pieces of functionality that are very useful and often less well known about Semantic Versioning. Let’s just assume the next version of Ubuntu is 15.0.0
Want to include something external in your version number like a stupid animal name for your adolescent user base? Semantic Versioning makes this possible with build metadata! Simply suffix the version number with a “
+
” (plus sign) and one or more dot-separated identifiers. For example, the next version of Ubuntu could simply be.15.0.0+puffin.25.04
Where “puffin” is the dumb animal name they’re using to market it
Where 25.04 is the release date (April of 2025) the version was first provided
Now they don’t have to drive everyone nuts with “puffin” and “25.04” in random locations. There is no spec on your build metadata. It’s left for you to define and it’s excluded in comparisons and sorting.
Want to provide a pre-release of your software? Semantic Versioning allows this as well: simply suffix the version number with a “
-
” (hyphen) and one or more dot-separated identifiers15.0.0-alpha+puffin.25.04
15.0.0-beta+puffin.25.04
15.0.0-rc1+puffin.25.04
It’s very typical for the build-metadata to include the git-SHA in a repeatable build situation.
Read The Spec!
Semantic Versioning is something you’ll use all the time. The spec is not long — only a couple of pages. It’s useful to read it once. It’s beautiful in its simplicity.