We are trying to decide on a good way to do version numbering for software components, which are depending on each other.

Let's be more specific:

Software component A is a firmware running on an embedded device and component B is its respective driver for a normal PC (Linux/Windows machine). They are communicating with each other using a custom protocol. Since, our product is also targeted at developers, we will offer stable and unstable (experimental) versions of both components (the firmware is closed-source, while the driver is open-source). Our biggest difficulty is how to handle API changes in the communication protocol.

While we were implementing a compatibility check in the driver - it checks if the firmware version is compatible to the driver's version - we started to discuss multiple ways of version numbering.

We came up with one solution, but we also felt like reinventing the wheel. That is why I'd like to get some feedback from the programmer/software developer community, since we think this is a common problem.

So here is our solution:

We plan to follow the widely used major.minor.patch version numbering and to use even/odd minor numbers for the stable/unstable versions. If we introduce changes in the API, we will increase the minor number.

This convention will lead to the following example situation:

Current stable branch is 1.2.1 and unstable is 1.3.7. Now, a new patch for unstable changes the API, what will cause the new unstable version number to become 1.5.0. Once, the unstable branch is considered stable, let's say in 1.5.3, we will release it as 1.4.0.

I would be happy about an answer to any of the related questions below:

  • Can you suggest a best practice for handling the issues described above?
  • Do you think our "custom" convention is good?
  • What changes would you apply to the described convention?

5 Answers 5


IMHO version numbers are like product names; important in that they're visible but unimportant in that they're decoration rather than content.

Still the version number, like a product name, carries meaning. And the most important thing you can do is avoid confusion. So here are some common expectations with respect to version numbers. To the extent that these exceptions are not met, the user will probably be confused:

Version numbers are monotonically increasing
This is probably the most obvious expectation, and at the same time the least likely to actually be true. At-a-glance, the user expects that version 2.3.5 comes after version 2.2.17, and has the same or better technology. But of course 2.3.x is a development branch, and 2.2.x is stable, and 2.3.5 actually was release back in 2004 and the 2.2 branch is still actively being worked on and 2.2.17 was released just last April and contains... well, you get the idea. You might as well just call version 2.2 "Potato" for all the meaning that the number carries. Welcome to version "Potato-17"!!

Similar Versions are Upgradeable/Compatible
If I have version 3.7 on my computer, and 3.8 comes out with all new shiny frozbots, I expect that with some upgrade or patch or whatever, my 3.7 can become 3.8 with no interruption. But if I'm on 3.7 and you release 5.2, I'm not so optimistic. Of course, I'd rather be pleasantly surprised rather than disappointed.

The first digit is significant
I wouldn't even bother to mention this if Java wasn't so prominently confusing on the matter. Unless someone told you, you would not expect that "Java 7" was actually version 1.7. And the first time you heard this, you response was almost certainly: "What? .. Why?"

Clearly the purist will say that the major version number will only change if the platform change is not backwards-compatible. But do you actually intend to drop backwards compatibility ever? Often major version revs are a marketing decision not a technical one; the Java absurdity comes from both camps having it their way at the same time, to almost comical effect.

As I just mentioned, version numbers are often as much about marketing as they are about technology. And that's OK, since that's kind of what version numbers are for: the inform you at a glance as to what's new about the software. Big number change means big functionality change. Small number change means almost no functionality change. That's what people expect. Whether it's true or not determines whether or not your version numbers carry the same meaning that your users think they do.

-- EDIT --
I forgot to mention this, but Caleb pointed it out nicely: Don't use version numbers to indicate anything important (e.g. stable/unstable) without making it otherwise explicit elsewhere. Yes, you know that the odd minor version number indicates development, but that makes one of us. Debian's "unstable" release moniker is a good example; or you could also use a totally separate product name; "Frozbot 1.2" for your product name, and "Devbot 1.3" for your development version.

  • 1
    Nicely put. On the last point, you may want to distinguish (i.e. don't confuse) marketing versions from technical, internally used version numbers. As in Java, Java 7 is a marketing version (sounds all new and shiny), 1.7 is the technical version (sounds like a minor improvement, which is quite accurate).
    – miraculixx
    Dec 7, 2012 at 11:51
  • While there are other good answers here, I like this most, since it it very well explains the different pitfalls and use cases. In the end we have settle with semantic versioning mentioned in a comment above, which is quite similar to what you have described.
    – bit-pirate
    Oct 14, 2013 at 8:27

Once, the unstable branch is considered stable, let's say in 1.5.3, we will release it as 1.4.0.

No-no. For unstable 1.5.3 stable must begin from 1.6.0 (and 1.4.x just missed, if you wan6t to use Semantic Versioning)


You're trying to use one value to indicate two separate things.

First, you've got a "version," which usually serves to identify the various releases and to indicate the order in which the releases were made. As tylerl said, the version should always increase -- it won't make any sense to users (and it could cause a lot of internal confusion as well) if you change the version from 1.5.3 to 1.4.0.

Second, you're trying to indicate is whether a given version is stable or not.

It's possible to indicate both things with a single "version number," just as some stores will use some pricing scheme to indicate whether an item is on sale. For example, prices that end in '3' at a store near me are final sale prices. That works well for the employees, who quickly learn how to spot a sale price, but it's not a great way to tell your customers about a sale. For that reason, they also put up signs near the sale items. You could do something similar, like making the least significant digit for stable releases even and and making it odd for experimental releases. I think, though, that if you're going to release something that's experimental, you should clearly mark it that way. You could add an 'X' at the beginning or end of the version string, like: X.1.5.3 or 1.5.3.X. You could even an experimental version number after that, so you could release multiple experimental versions all based on the same base version: 1.5.3.X1, 1.5.3.X2.

You should also consider that there's a long tradition of using "alpha" and "beta" version numbers to indicate versions that may not be stable or complete: 1.5.3a54. Make sure you have a good reason for departing from this scheme if you decide to do anything else, because you're probably going to have to explain anything else to your developer community.

  • 1
    +1 Brilliant example: "prices that end in '3' at a store near me are final sale prices...but it's not a great way to tell your customers about a sale."
    – tylerl
    Dec 7, 2012 at 17:22

I would suggest to use the major.minor.patch format, using an extension "tag" for stable/unstable versions, and a definite meaning of the major and minor numbers:



major  only changes if there are incompatible changes in the API
minor  changes if there are changes in the API but backward compatibility is given
patch  any other changes, could be the build number or any other increasing number
-stable indicates the stable version
-unstable indicates the unstable version

This way dependencies are easily managed and will tell each component client/user when they have to pay more attention to new versions. E.g. if component A (1.1.0-stable) depends on B (5.4.534-stable) and a new version of B is due (6.1.0-unstable) one is immediately aware that A will have to be changed, possibly substantially.


I really love the way Hibernating Rhinos has been building RavenDb vis-a-vis versions -- they just have an ever increasing build number. When they get a stable one it gets marked stable. But everything is a release candidate.

  • 3
    they just have an ever incriminating build number - Dear god I hope that's actually what you meant, it really changes the context of version numbers if they get increasingly incriminating.
    – tylerl
    Dec 7, 2012 at 17:12
  • 1
    Damn you autocorrect . . . Dec 7, 2012 at 17:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.