I expected to read this and furiously disagree with the author, but I 100% agree with the point that is being made. I just don't think it is semantic versioning that is to blame.
It would be nice to see more responsibility taken for backwards compatibility. Realize that any amount of time saved in not maintaining backwards compatibility is going to be wasted, many, many times over, by all your downstream users that have to rewrite their code, or to re-learn how to use end-user software. We are not being nice to each other and social (ideally economic) pressure ought to punish those that do that. We should stop pretend that a product is still the same after a breaking major version change.
Interestingly the only examples of great handling of major versions that I can think of are from games. There are many games that have new major versions published (say, Warcraft 3) that still allow you to keep playing the old major version, still make it possible to buy the old version, still support both versions, and make it trivial to have both installed if you want that. Something that ought to be perfectly normal behavior that we could expect from all software.
Nah. Versioning is good, the main issues is that not everything can be usefully versioned, and some people lack discipline.
But there's plenty projects out there with perfectly good, reliable versioning.
What I do think is an annoyance is that you rarely see Linux actually use it. Linux is excellently well prepared for allowing libfoo.so.1.4 and libfoo.so.2 to coexist on the same system.
But it's rare for a Linux distro to actually package both versions 1.4 and 2.0 of something, and I've never even seen a project that doesn't even specify a version to link to, and just adds `-lfoo` to the linker flags. So building old code can become a huge problem, even though in theory it absolutely doesn't have to be.
Raise your hand if you always come up with the perfect API on the first try.
If you demand no breaking changes ever, that means you are insisting on staying with an imperfect API forever. Isn’t it better to iterate towards something better? Strive towards perfection? No, you just want everything you use to be someone’s first draft because changes aren’t allowed?
Well, even though the API isn’t perfect, you used it as a dependency in your own project. It’s good enough for your needs, and you don’t need those changes. The imperfect is good enough. You just don’t want more work of having to update. I get it. We’re all lazy.
The real mistake here is that very new and immature packages are becoming popular way too early on in their lives. People just can’t resist the new hotness. If you want a stable API, use things that are very old and have already been polished extremely thoroughly. They made their breaking API changes long ago, and now they are much less likely to change.
I know we all laugh when people keep the beta tag on their software for way too long after they already have tons of users depending on it. GMail was a notable example. But maybe that’s not wrong. Maybe wave that beta flag high up for several years until you are sure you have figured it out and are ready to stop making API changes.
If you think about the packages the author uses as an example, like node and react, I don’t think the beta flag would have necessarily been innacurate.
This headline is slightly dramatic*. The far worse thing with semantic versioning is that it became part of our company’s culture of collaboration. Semver sat too easily alongside multiple repositories, small uncouple components, and teams sitting in silos. There were only fifty of us!
You are beholden to use semantic versioning (and changelogs and READMEs) when there is only a one way communication channel with the consumers of your software. You can’t see their call sites so when you deprecate print_beermat() to manufacture_coaster(style=BEER), the best you can do is warn them both numerically and in writing**.
When you operate a business where all the developers are on the same team then it is crazy — unless you have thousands of SWEs — to communicate in this way. Much better to (1) rename the function (2) fix all the call sites and (3) put it up as an atomic changeset. You’d like to think I was preaching to the converted but I still see this practice happening occasionally.
* Their thesis is that authors of popular software change their APIs with reckless abandon, which semantic versioning enables.
** Or, as the original author says, just don’t delete the old print function.
> When you operate a business where all the developers are on the same team then it is crazy
Even if it's not a single team, it's still crazy most of the time. I've been in orgs with tens of teams, each operating anything between 1 and 15 microservices where there was never the need for SemVer.
Upgrade strategies that span across teams are not hard if there's good telemetry and good communications. Add a new endpoint with the new desired behaviour; deploy it; communicate to your users; track usage of the old endpoint, and when it comes down to zero delete it.
Adjust this process as required (e.g. send comms in advance, give deadlines, work with consumers to expedite, maybe negotiate more time to transition, etc).
This decouples producer from consumer updates, gives everybody a chance to self organise and keeps things moving.
> Here’s the problem: people interpret SemVer as permission to make breaking changes.
So, it isn't SemVer that is a mistake. It's the author's opinion that software should always be fully backwards-compatible, which would then require all SemVer-using software to be version 1.x.x (or 0.x.x, if we're zero-indexing.)
Or, alternatively, if SemVer didn't exist, this post would probably skip it altogether and just complain about people breaking backwards compatibility anyway.
> To say it another way: If you need to make a breaking change to your API, it means you screwed up. Don’t screw up.
If you make mistakes, please don't make mistakes instead. News at 11.
I agree. SemVer doesn't give you permission to make breaking changes -- it documents your decisions, assuming you're honest with SemVer.
This is very very useful. You can look at a library or dependency and weigh out if frequent, breaking changes are ok for you or not -- is the value worth the pain? Alternatively, if the major version never changes, you can have more confidence that you won't have to rework your code on every library update.
It would be nice to see more responsibility taken for backwards compatibility. Realize that any amount of time saved in not maintaining backwards compatibility is going to be wasted, many, many times over, by all your downstream users that have to rewrite their code, or to re-learn how to use end-user software. We are not being nice to each other and social (ideally economic) pressure ought to punish those that do that. We should stop pretend that a product is still the same after a breaking major version change.
Interestingly the only examples of great handling of major versions that I can think of are from games. There are many games that have new major versions published (say, Warcraft 3) that still allow you to keep playing the old major version, still make it possible to buy the old version, still support both versions, and make it trivial to have both installed if you want that. Something that ought to be perfectly normal behavior that we could expect from all software.