What is Semantic Versioning (SemVer)?


Software Versioning

Software versioning has always been a problem for software developers, release managers and consumers since time immemorial. For developers, the challenge lies in releasing new breaking changes while simultaneously minimizing consumer upgrade pains. On the flip side; consumers, when they finally decide to upgrade to new-shiny-release-10000, want to be sure they are not buying a one-way-ticket to dejection-land. Add release managers who have to manage both parties to the mix and you’ll get a sense of the chaos.

Versioning is even more of an issue in current times with the rapid viral proliferation of tools, frameworks and libraries. This post explains what Semantic Versioning is, why it is needed and how to use it.

Semantic Versioning (SemVer)

Semantic Versioning was proposed by Tim Preston-Werner (apparently he founded Github too). The goal was to bring some sanity to the management of rapidly moving software release targets.

SemVer provides a standardized format for conveying versioning information as well as guidelines for usage. Thus, software release information becomes meaningful (cue semantic) -a glance at the number describes what to expect when consuming a new update or new piece of software. No more groping in the dark or taxing deductions…

But why SemVer? Can’t software developers just use any versioning style they like? Sure, you can update your local releases and call them whatever you like e.g. blue orange, green banana or orange coconut. These styles work fine if you live under the sea or don’t care about others using your code. In the real world, software developers collaborate and consumers need to easily know if the blue orange->green banana upgrade is not going to break their entire stack. A standardized format that everyone agrees on and understands is a likely fix and this is what SemVer does.

So SemVer…, a.b.c what?

At least three numbers are required to identify a software version; these are explained below:

major . minor . patch

For example, version 3.10.1 of lodash has a major version of 3, a minor version of 10 and a patch version of 1.

How do I use these numbers?

Each of these three numbers signifies the changes in the released version of software; i.e. before a new set of changes go out, you want to bump up one of these numbers to correctly match and convey information that describes it. The heuristic is thus:

  • New changes that break backwards compatibility require a bump of the major version number. The upcoming Angular release, which is not backwards compatible, is thus tagged 2.0 and not 1.5 or 1.6.
  • New features that do not break backward compatibility but are significant enough (e.g. adding new API methods that didn’t exist before) would bump up the Minor version number.
  • Small (maybe insignificant changes e.g. bug fixes) would bump up the patch number. These have to be backward compatible too.

How do I use the numbers?

Consuming new software

So you run into an awesome software on Github that uses semantic versioning and is at version 2.1.6. The software meets your needs and you want to integrate it right away, the following guide provides a heuristic for asking questions.

 2 – There have been two major releases.

  • What does the community think about the project’s continuity?
  • Is the first version deprecated or still being maintained?
  • How was the backward breaking major release handled? Did the authors get community support and feedback?

 1 – There has only been 1 minor update since the v2 major release.

  • Not too many features have been added, is the project active?
  • Are there plans to add more features or is the software mature?

16 –  16 patches!

  • Are the 16 patches bug fixes or just minor upgrades?
  • Does the project have a quality concern?
  • Is the software stable or does it break?

Upgrading existing software

There has been a new release of library foobaz – the core engine powering your software stack. Assuming the current consumption version is v1.2.3, the below explains likely actions based on new release version numbers:

v2.0.0 – This is a major bump and pre-existing contracts might be broken. A major update nullifies any pre-existing contractual obligations (that’s lawyerese for ye nerdy folks), so don’t jump on the bandwagon until you know the full impact of the changes.

v1.∞.∞ – This should be pretty safe, minor and patch bumps typically do not break backwards compatibility. So go in, update and start using the new features.

NPM and SemVer – the upgrade link

Open up a package.json or bower.json file, you’ll typically see a devDependencies or dependencies section with key-value pairs that looks like this:

"dependencies": {
"lodash": "~3.8.0",
"angular": "^1.3.0",
"bootstrap": "^3.2.0"
}

What do the ~ and ^ stand for? They determine what versions you upgrade to when you run npm update. Thus for the sample above, an update will allow newer versions based on the table below:

Special Character Version Allowed Upgrades Notes
^ ^1.3.0 1.*.* All backward compatible minor/patch updates
~ ~3.8.0 3.8.* All backward compatible patch updates

Note: This post only explains ~ and ^; there are more characters (e.g. >=, *, etc) and these should be explained in an upcoming post inshaaha Allaah.

3 Extra things to know about SemVer

Beware of 0.*.* 

The semver spec doesn’t track any release below 1. So if you plan to use some software tagged as 0.9.9 just be ready to redo your work any time (read my EmberJS story). These are libraries in development and terrifying things can happen, for example, the author(s) might never publish a production ready version or might simply abandon the project.

In short, SemVer does not cover libraries tagged 0.*.*. The first stable version is v1.0.0.

Start at 0.1.0

And this makes sense, doesn’t it? Projects typically start with a feature and not a bug fix. And since you would probably tweak a couple of things before becoming stable, it doesn’t make sense to start out with a major version bump. Unless of course, you are only publishing your closed-source code.

Identifiers for PreReleases And Builds

Valid identifiers are in the set [A-Za-z0-9] and cannot be empty.

Pre-release metadata is identified by appending a hyphen to the end of the SemVer sequence. Thus a pre-release version of some-awesome-software could be tagged v1.0.0-alpha. Note that hyphens are allowed in names for pre-release identifiers (in addition to the set specified above) but names cannot contain leading zeros.

Build metadata is identified by appending a + sign at the end of the patch version number or at the end of the prerelease identifier; leading zeros are allowed. Examples include v1.0.0+0017, v1.0.0-alpha+0018.

Criticism

Jeremy Askhenas (of underscore and backbone fame) has written a critique of SemVer; arguing that it is no silver bullet and most big software projects do not use it (e.g. node, jQuery etc). There is also ferver too…

Nevertheless, it is worth knowing that you SHOULDN’T absolutely rely on version numbers as implying SemVer compliance (cos developers are human afterall…), you should read up the project docs and ask the maintainers if you have questions.

Still curious? Read Why JavaScript ‘seems’ to get addition wrong.