Semantic Versioning is a specification for version numbers. It specially makes sense for software libraries and for everything what can be a dependency in a bigger system. A semantic version number always follows this pattern MAJOR.MINOR.PATCH.
- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backwards-compatible manner, and
- PATCH version when you make backwards-compatible bug fixes.
Let’s say you are the maintainer of an open source library, an XML parser, with the version number “1.0.0”. And now you want to release a new version because you fixed some bugs. For the bug-fix you
- changed some method implementations,
- but you didn’t add new methods
- and the changes are backwards compatible
In that case the new release is just a patch. That means you would update the patch version in your version string. That would be “1.0.1“.
Now let’s say you want to add additional features to your software library. The current version “1.0.1” can read XML files from hard disk and now you want to add a new feature which allows to read XML files from the Internet. For this new feature you are adding new methods and you extend the public API of your library. That’s why you count up the minor version in your version number. So the next release looks like this “1.1.0″. And every time you count up the minor version you have to reset the patch version to 0.
During your work on this XML parser you learned a lot of new stuff and you decide to completely refactor the library to make it even more awesome! During the refactoring you change the public API on the library and the new version is not backwards compatible anymore. That’s why you release version “2.0.0″. It’s a major version! Every time you count up the major version number you have to reset the minor and patch version to 0.
People who rely on your XML parser can now immediately see that the new version will, very likely, lead to compilation errors and break their build. Seeing the version number they now know that they have to be careful with the update, they have to check the change logs and the migration path.
Semantic versioning is awesome, because you can see immediately how big the changes are without digging into documentation and source code. Already on the version number you can see if you can
- easily update that library (Patch) or
- their are new features to check out (Minor) or
- you have to be careful because the update will break your system (Major).
It makes the life of software developers so much easier!
Unfortunately not all open source libraries are using semantic versioning. Some of them are using very wired version numbers. For example this here:
That’s a timestamp version number, including year, month, day, hour and minute. Unfortunately that doesn’t tell me anything about the changes in that release. I don’t know if that is just a patch release or maybe a major release that will break my build! Or maybe it is a minor release with new features. But who knows? This kind of version numbers are totally bullshit!
Check out the full spec at semver.org. It takes less then 5 minutes and it will make you to a better software developer. I promise!
I just showed here an easy going example. Semantic versioning is more then just 3 numbers and 2 dots. It also supports pre releases and build numbers and the whole version string can be more complex. For the complete syntax check out the Backus–Naur Form Grammar for Valid SemVer Versions.
By the way, I’m working at VersionEye, a notification system for software libraries. If you want to know if a software library is using semantic versioning, just visit it’s page at VersionEye and you will see a green or red hint like here for Ruby on Rails.
Follow the discussion on Reddit.
5 thoughts on “Semantic Versioning”
Great to see you embrace semantic versioning and thanks for the nice writeup adressing library developers!
I already saw the new feature in action on versioneye and found it nice but I think the langage (see screenshot, too) should communicate much clearer whether it’s just the version number matching the formal 1.2.3 pattern (syntax) or whether the library actually does the semantics of semantic versioning.
Thanks for the kind words. But how can we check if the library is really doing the semantics of semantic versioning? That would require source code analyzes. Right? Or do you see another way?
Semantic Versioning is both a design pattern and a buzzword. Semantic Versioning does not guarantee that the design pattern is applied the right way nor that is makes sense for your specific application. The most important feature of Semantic Versioning is taking care of backwards-compatibility of your API. This is a difficult task that in fact requires code analysis, good test coverage or other mechanisms is software mangement. Please don’t just assume that the label Semantic Versioning automatically solves any problem that cannot be solved without it.
Totally agree with you. There are some examples where semantic versioning was used the wrong way and they didn’t apply the design pattern. Using code analysis to ensure that the public API was not changed is a good thing. But I guess most of the projects don’t do that. But even without code analysis semantic versioning is a good thing, because it encourages people to think about their releases and their version numbers.
And most of them get it right. As soon I get notifications from VersionEye that there are new patch & minor versions out there for my project dependencies, I update them and I run my tests. And it never broke my build! That means for me the Ruby community applies the design pattern correctly.