(I’m writing this post primarily so I can link to it in an internal document on Monday. There’s nothing sensitive or confidential here, so I might as well get it down in a blog post.)
SemVer is pretty clear about pre-releases. Any version with a major version of 0 is considered “initial development”, and anything can change at any time. Pre-releases – versions which have a hyphen after the regular version number – are also considered unstable.
In any project, I used to use 0.x to start with and then progress to 1.0.0-alpha01 or similar1 at some point. I’ve stopped doing this now.
For any project I start now, the first release will be 1.0.0-alpha01 or 1.0.0-beta01. The reason? Consistency. With this scheme, never releasing anything with starting with “0.” there’s a very consistent story about what the pre-releases for any given version are: they’re that version, with a hyphen after it. So for example:
- The pre-releases for 1.0.0 are 1.0.0-alpha01, 1.0.0-alpha02, 1.0.0-beta01 etc
- The pre-releases for 1.1.0 are 1.1.0-alpha01, 1.1.0-alpha02, 1.1.0-beta01 etc
- The pre-releases for 2.0.0 are 2.0.0-alpha01, 2.0.0-alpha02, 2.0.0-beta01 etc
All very consistent. Whereas if you use a major version of 0 as well, just version 1.0.0 is treated specially. It gets pre-releases of 0.1, 0.2, 1.0.0-alpha01, 1.0.0-alpha02, 1.0.0-beta01 etc. I’m fine with things being inconsistent when there’s a good reason for it, but I don’t see any benefit here.
While you might argue the case for a difference between “initial development” and “first alpha release” I suspect that’s almost never really useful. It’s hard enough working out exactly when to move from alpha to beta (and documenting the reasons for that decision), without having a “pre-alpha” stage to consider.
This isn’t something I feel strongly enough to put effort into persuading the world – I’m not on an anti-0.x crusade – but if this post happens to have that effect, I’m not going to complain :)
1 SemVer would actually suggest using 1.0.0-alpha.1 instead of 1.0.0-alpha01. Dot-separated identifiers are compared for precedence, and identifiers which are only numeric are compared numerically. So 1.0.0-alpha.11 comes after 1.0.0-alpha.2, which is good. However, using 1.0.0-alpha02 and 1.0.0-alpha11 gives the same effect, without having to worry about anything that uses lexicographic ordering. There’s still a problem when you reach version 1.11.0 version 1.2.0 of course. My point is that this post documents what I currently do, but you may well wish to have a different flavour of prerelease.
6 thoughts on “Why I don’t start versions at 0.x any more”
There’s also a risk of never getting past 0.x. I know many projects that are years old and are still in version 0.x (e.g. Cake), even though they work fine. It’s as if the maintainers can’t commit to saying their project is now stable.
LikeLiked by 2 people
The idea behind 0.x versions is “rapide development” (https://semver.org/spec/v2.0.0.html#doesnt-this-discourage-rapid-development-and-fast-iteration), also known as “I don’t have a clear idea of what I am doing”, and “the public API can change /radically/ at any time”.
With npm for instance, the caret ^ range specifier is supposed to pin only the major version (^2.4.6 can be replaced by any more recent 2.x.y version, like 2.5.0).
But for a major version 0, like “^0.3.0”, it actually means: “depend on 0.3.0 and nothing else” (not 0.3.1 or 0.4.0): https://stackoverflow.com/a/42054532/6309.
Hence a major version “0” is different from a 1.0(-alpha/beta), where the API can still change, but not “drastically”, and should lead to a stable (API-wise) 1.0.0 release.
So I would argue there is a use-case for 0.x versions.
But yes, knowing when to pass from “work in progress” to “this is what it should look like for a future 1.0 release” is tricky.
Another option for that initial “rapide development phase”: don’t use 0.x version and name them differently.
Go, for instance, used “revisions”: https://golang.org/doc/devel/pre_go1.html
LikeLiked by 2 people
I would expect an alpha API can still absolutely change drastically. My expectations would be for beta to be “more stable” but still really anything could change.
I agree. “alpha”, “beta”, or “GA” can also be used as “feature gates”, as seen for example in Kubernetes (https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/#using-a-feature).
And yes, in “alpha” (or “experimental”), everything can change, without notice.
I still like my “0.x” versions, though, while I still have not even a clear idea of the general boundaries of the system I am coding.
I would use 1.0.0-alpha.1 instead. this allows me to go well over 1.0.0-alpha.99 if I need to.
I am honestly unsure how useful SemVer actually is. Most of the time, I would be happer we just an increasing number per release, like FF and Chome do it.
If you are very enterprisey, releasing patches can be mandatory, but tbh that’s not the case for many products.