The problem of breaking changes and version numbers
- Published at
- Updated at
- Reading time
We were discussing version numbers at work the other day, and, as always, things are complicated. How do you version a
beta release? Should projects start with
0? And do you follow proper semantic versioning or not?
I don't hold strong opinions here, but I do care about setting expectations appropriately. When I update a dependency, I'd like to know if there are expected breaking changes or if it's supposed to be a smooth ride.
The idea of a breaking change is by itself very complicated. Let's say there's a bug in your software; when people already use your code there's a slight chance that a bug fix could also be a breaking change.
But I'll leave this topic for another day...
It really doesn't matter what numbers you slap onto your package, but folks depending on your code should get guidance on what to expect.
And this is when things get more complicated. How do you communicate these breaking changes?
Suppose you install a new package via
npm: you'll find a caret range definition (
^) in your
package for your installed package. But what versions does a caret range include?
Here are some examples:
^1.2.3 := >=1.2.3 <2.0.0-0 ^0.2.3 := >=0.2.3 <0.3.0-0 ^0.0.3 := >=0.0.3 <0.0.4-0
And you see that right — the
^ behaves differently depending on the overall version number.
For every package that reached
^1 includes all updates up to but excluding
2. Contrary, if you're dealing with a zero-leading package, it'll only go up to the left-most non-zero element in the version number.
^0 only accepts
The idea behind this is the communication of breaking changes that are "somewhat" based on semantic versioning. SemVer defines it is as follows:
x.y.z -> 2.3.1 x change: backwards incompatible changes are introduced y change: new features are included but everything's backwards compatible z change: backwards compatible bug fixes are included
And following, according to SemVer everything pre
1 should be considered a breaking change:
Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.
But in practice and enforced by npm: going from
0 is considered a breaking change.
Do your dependency maintainers follow this rule? I don't know — but it proves the points once more that you should rely on proper test coverage and don't treat dependency updates lightly.
The next breaking change is just around the corner! 🥷
Yes? Cool! You might want to check out Web Weekly for more web development articles. The last edition went out 14 days ago.