I want to make some of my packages v1 but there is a nagging fear that the API isn’t stable.
I wonder if there good guidelines and article out there to help me decide if I should do it? API is stable is a criterion, but it seems to be hard to decide when API is stable. Knowing when is something I am seeking guidance on.
Don’t worry about API stability, there is always the next major version
Hmm, v1 looks big. Pandas only just got v1 after a decade? So I want v1 to mean stability and ppl can rely on it. Is that too old fashioned thinking?
I think yes, in the case of Julia. In my mind the benefits of being in normal semver territory (i.e. >=1.0.0) are just too big in the case of Julia. Given that the package resolver behaves differently for versions <1.0.0, and that people tend to want to increase a more significant number than the patch number for new features, and that non-breaking minor version increases for versions <1.0.0 cause real pain for depending packages, I think just tagging 1.0.0 is the right call in most situations in Julia (except maybe if you are really still just experimenting around).
I also have to admit that I always thought it to be almost silly when projects that have very large user numbers stay beyond 1.0 for years. I think once one has a significant user base, one has to be responsible about questions of stability and backwards compat, not by some magical “now it is 1.0.0” arbitrary time point.
I read this differently. V1 is the developer commitment, before v1 there is no commitment from developer on stability. Nothing the developer has the right to say i am non-breaking even if there are 6 billion users.
According to Julia’s “extension” of SemVer, there is no need for pre-v1 packages to increase minor version when the release is non-breaking.
In particular, a package may set
version = "0.2.4" when it has feature additions compared to 0.2.3 as long as it remains backward compatible with 0.2.0.
But they always do, all the times, and unnecessarily create work for downstream packages! I think it is just psychology, no one wants to just increase the patch version after one has created something new and cool
If the package devs can’t resist the urge to use version numbering as an advertisement and disregard the stability of the downstream software, I’d be worried if their operation of the post-v1 software is stable and SemVer-compliant enough.
But I don’t think that’s the reason behind unnecessary minor bumps. Pre-v1 behavior is Julia’s extention to SemVer. Unlike SemVer itself which has a clear specification (https://semver.org), Julia’s interpretation does not have a clear specification (at least it’s not done as formal as SemVer).
This “commitment” is a very weak one: it just means that you bump major/minor versions in accordance with SemVer when you need to.
You can do this 35 times a day and reach version 1000 in a month, and still conform to SemVer.
I agree with @davidanthoff: the 0.x range is fine when when you are experimenting with the package (but during those days, you may not make any releases at all), but as soon as others (want to) use it as a dependency, it is basic courtesy to go to 1.x.
This is not a big deal and has a tiny cost for the developer from then on. You are still free to experiment, especially in branches etc, as long as you don’t release.
What’s everyone’s opinion on versioning when you know you’re going to change part of the API?
Release as a major version, when you change the API, bump the major version
I’d suggest to not release v1 if you think you are going to change the stable API within a year. I’d understand the recommended period of time varies person to person. But hopefully even @davidanthoff and @Tamas_Papp say “within a week” is way below their threshold.
If there is a subset of API that may change but it’s not the most important subset, you can always declare them as an experimental API that can change across minor bump. That’s how
Threads.@spawn. The consequence of this to the downstream packages is that (strictly speaking) they need to add compat bound by minor version than major version if they use such features.
This is exactly why SemVer alone is not enough. See, e.g., how Go is adding a twist to SemVer https://www.youtube.com/watch?v=F8nrpe0XWRg
I see zero harm in that. I mean, probably downstream users will get a bit suspicious of your package if you break things that often, but that seems to be related to the frequency of breaking stuff, not what version you pick.
Yeah. I think I often try to think deep and say, is this API not gonna change? Really really not gonna change?
That is way too strict. If you wait until you think your public API will never ever change, then you will never end up releasing v1.0.
It is perfectly fine to make breaking changes after 1.0. That is exactly why SemVer has major versions.
SemVer says that you should release 1.0 as soon as other people depend on your software.
It’s worth reading the full SemVer website:
I know @stefankarpinski had some thoughts about adding some of Go’s SemVer extensions to Julia.
But until then, the current state is that Julia implements SemVer (with some slight modifications for 0.x.y versioning). So we should use SemVer as it is implemented in Julia.
Please note that I didn’t say “never.” I brought up a concrete timescale. Stability is a property with respect to time. Without bringing up a concrete timescale, I don’t think we can come up with a meaningful guideline.
I think Numpy folks get this right. See NEP 29 and NEP 23.
If you have a stable API on which users have come to depend, you should be 1.0.0.
(bold styling by me)
I was more referring to this:
If your software is being used in production, it should probably already be 1.0.0.
I agree with you that a time scale is helpful for providing a heuristic/rule-of-thumb.
I would suggest these rules-of-thumbs:
- If it’s being used in production, it should probably be 1.0.0.
- If you have one or more people publicly depending on your software, and you haven’t made any breaking changes to the public API in 2 months or longer, it should probably be 1.0.0.
- If you haven’t made any breaking changes to the public API in 6 months or longer, it should probably be 1.0.0 even if no one is publicly depending on your software.
Of course these would just be rules of thumb. At the end of the day, I suppose it is up to each individual developer. Certainly I myself am guilty - I know that I have packages that don’t follow the rules of thumb I listed above.
Thanks! This was all very helpful. I’m assuming that the more modular approach Julia takes on for package management makes it a little easier to reach 1.0 too. For example, if I have a huge package like Numpy it’s hard to be sure the entire thing is stable until a very long time. But if I’m just handling a handful of methods it’s easy to make some stable stuff and build around it.