Are different version naming conventions suited to different projects? What do you use and why?

Personally, I prefer a build number in hexadecimal (e.g 11BCF), this should be incremented very regularly. And then for customers a simple 3 digit version number, i.e. 1.1.3.

1.2.3 (11BCF) <- Build number, should correspond with a revision in source control
^ ^ ^
| | |
| | +--- Minor bugs, spelling mistakes, etc.
| +----- Minor features, major bug fixes, etc.
+------- Major version, UX changes, file format changes, etc.
  • Why hexadecimal and not regular decimal system?
    – Make42
    Commented Feb 22, 2021 at 17:38

13 Answers 13


I tend to follow Jeff Atwood's opinion of the .NET convention of version numbering.

(Major version).(Minor version).(Revision number).(Build number)

More often than not, for personal projects, I find this to be overkill. The few times where I have worked on substantial projects like search engines in C# I've stuck to this convention and have been able to use it as an internal tracker effectively.

  • 1
    This tends to follow the pattern I've seen used successfully in many projects, large or small. It is very effective. Commented Oct 16, 2010 at 12:09
  • 1
    How does/should "build number" relate to "changeset identifier (hash)"? Is it part of the hash, incremental, or something else? Commented Jul 23, 2013 at 13:28
  • @Jace, where I work we use Mercurial, and go off the changeset number. We only ever push to/pull from a single repository, so the number is not unique to the specific checkout. We then have [major].[minor].[changeset] accordingly (though the major and minor numbers are often more marketing than indicative of progress since the last version).
    – Wai Ha Lee
    Commented Feb 8, 2015 at 21:37
  • 1
    Does "build number" imply that it's just minor tweaks like bug fixes? Should any new functionality at least get its own revision number? Commented Apr 5, 2017 at 14:44
  • 2
    I encourage everyone to actually read the article that Mike B is referring to. Atwood suggests to NOT use the .NET or any numbered versioning and use date-based versioning instead.
    – Stefan
    Commented Jan 12, 2018 at 20:45

Semantic Versioning deserves a mention here. It is a public specification for a versioning scheme, in the form of [Major].[Minor].[Patch]. The motivation for this scheme is to communicate meaning with the version number.

  • Surprised this isn't getting more love. Commented Jan 19, 2012 at 17:48
  • I was a little late to the party... I added this answer 9 months after the original question. ;-) Commented Jan 19, 2012 at 19:12
  • Looks like this works out to be the same as the RubyGems Rational Versioning policy that I mentioned below, only better formalized.
    – Ken Bloom
    Commented Oct 9, 2012 at 23:59
  • 10
    SemVer is meant for versioning APIs, not user-facing software: "Software using Semantic Versioning MUST declare a public API." So technically, you can't use SemVer without a public API. However, it might make sense to adopt something similar to SemVer for versioning user-facing applications.
    – Ajedi32
    Commented Apr 1, 2014 at 16:18
  • 4
    @Ajedi32 For example if an user-faced software saves files, then the author could declare the file format as their "public api" and version the software accordingly (all ui changes are minor/non-breaking and format changes are major).
    – beppe9000
    Commented Jul 5, 2016 at 17:53

I don't use it but I have seen and it's an interesting structure:


Self explained.

  • 4
    And you always know how fresh is your code..! :)
    – Lipis
    Commented Sep 14, 2010 at 1:43
  • 3
    this is also similar to Ubuntu's version numbers. They do year.month Examples: 10.04 and 10.10
    – Brad Cupit
    Commented Nov 13, 2010 at 2:38
  • 10
    It's worth mentioning that this only works well for a system which either doesn't have compatibility issues (a website), or inherently always has incompatibility (an ubuntu release).
    – jkerian
    Commented Dec 17, 2010 at 21:41
  • 2
    @jkerian, why does compatibility matter for this?
    – AviD
    Commented Jan 3, 2011 at 10:30
  • 16
    @AviD: I'm a bit confused about why you're asking this, since nearly every other answer to this question shows version systems that include compatibility information. Your choice depends on what information you want to record with your version numbers. For my purposes, a date has basically no meaning (just starting at v1 and incrementing every build would be an improvement). Do you ever branch? do you ever release "new patch on old code" while releasing "new version"? But for something like a website or operating system, a date-based system seems quite appropriate.
    – jkerian
    Commented Jan 3, 2011 at 16:28

I try to use the RubyGems Rational Versioning policy in which:

  • The Major version number is incremented when binary compatibility is broken
  • The minor version number is incremented when new functionality is added
  • The build number changes for bug fixes.
  • 5
    This is essentially known as Semantic Versioning : semver.org
    – Patrice M.
    Commented Oct 31, 2013 at 10:52
  • 4
    @PatriceM. Thanks for sharing that link. semver.org didn't exist when I wrote that answer.
    – Ken Bloom
    Commented Oct 31, 2013 at 11:47

Here is very fine-grained approach to version numbering:

  • N.x.K, where N and K are integers. Examples: 1.x.0, 5.x.1, 10.x.33. Used for intermediate builds.
  • N.M.K, where N, M and K are integers. Examples: 1.0.0, 5.3.1, 10.22.33. Used for releases.
  • N.x.x, where N is integer. Example: 1.x.x. Used for support branches.
  • N.M.x, where N and M are integers. Example: 1.0.x. Used for release branches.

Here is the picture for simple illustration of version numbering approach:

Agile version numbering

PA means pre-alpha A means alpha B means beta AR means alpha-release BR means beta-release RC means release candidate ST means stable

Advantages of such version numbering approach are following:

  • It represents specifics of agile software development lifecycle.
  • It takes into account specifics of source code repository structure.
  • It is self explaining for those who got used to the patterns. Every pattern represents different artifact. Such patterns can be easily parsed and used for other purposes, such as issue tracking.
  • Versioning patterns set, which basic for the described versioning approach can be used for gathering metrics and planning.
  • It is focused on the concepts of maturity and level of quality. Very often such version numbers as 1.0.0 are assigned without much necessity (when software is in deep alpha). Presented version numbering approach allows to establish several levels of maturity. In the simplest case it will have only two levels: intermediate build (N.x.K) and release (N.M.K). Release means that piece of software with full version number (N.M.K) has gone through some kind of quality management process within the supplier company/organization/team.
  • It is an evidence of agile nature of both development and testing.
  • Encourages modular approach to the software structure and architecture.

There is also more complex diagram representing versioning approach in details. Also you might find useful presentation slides describing transition to the versioning approach. Presentation slides also explain why it is important to stick to the same versioning approach throughout the whole life of the software project.

Personally my attitude towards using date version instead of real version numbers assumes that developers of the software with dated versions:

  • Know nothing about software development lifecycle. Development is usually agile and iterative. Version numbering approach should represent iterative nature of software development process.
  • Do not care about software quality. Quality control and assurance are agile and iterative. Just like development. And version number should be the evidence of agile and iterative nature of both development and quality control/assurance.
  • Do not care about architecture or idea of their application. Major version number (N in N.M.K) is responsible for both architectural solution and underlying principle of the application. Major version number N is to be changed accordingly to the changes in architecture or changes of major ideas and principles of its working/functioning.
  • Do not have control over their codebase. There is probably only one branch (trunk) and it is used for everything. Which personally I do not think is right as it encourages codebase to become one large garbage dump.

This approach might seem a little bit controversial, but I believe this to be most straightforward way of giving software appropriate version numbers.

UPD (Feb-2021): I have also created a web-site https://versioningright.com aiming to explain deeper principles of software versioning that remain hidden behind the scenes.

  • First link down...............
    – Pacerier
    Commented Jan 8, 2015 at 7:11
  • Third links is also down. Also: Is there video to the presentation slides?
    – Make42
    Commented Feb 23, 2021 at 0:02
  • @Make42: There is no video unfortunately. But I have been working on the concept a bit and now the most recent developments are described at the versioningright.com page
    – altern
    Commented Feb 24, 2021 at 3:35
  • Thank you! I already found your website. I will have a deeper look. I went through all of your slides and liked them a lot. It seems to me that you extend the (standard) idea that (a) difference in the first version number are non-backwards compatible (you switch the phrasing saying that the older version branch - the support branch - cannot be merged back into the newer version branch), (b) differences in second version number can be merged together (you say that the "release" branch can be merged back) and (c) differences in the third version number just indicate consecutively versions.
    – Make42
    Commented Feb 24, 2021 at 16:17
  • Two extensions that I see are: 1. That you see it from a perspective of merging instead of compatibility - but these two views are a one-to-one mapable. 2. You give branches themselves a versioning scheme by introducing the "x". A third extension is less about version numbers but more about the branches: 3. You introduce the branches PA, A, B, AR, BR, RC, ST. It seems to me that none of these extensions is new by itself but the way you bring them all into a framework is the (excellent) contribution. Did I get this right?
    – Make42
    Commented Feb 24, 2021 at 16:21

For every major version you release, it's not uncommon to have a working version you call it internally. For instance, at my last job, we referred to a major version with the following Ubuntu-inspired naming convention:

[sickly condition] [alliterative animal name]

Which gave such names as "Limp Lamprey", "Wounded Wombat" and "Asthmatic Anteater".

Make sure unless it's a truly cool name that it doesn't leak to your customers.

  • 4
    Seems like an inefficient use of time and energy.............
    – Pacerier
    Commented Jan 8, 2015 at 7:16
  • 22
    So was leaving that comment, but it didn't stop you. Commented Jan 8, 2015 at 12:46
  • It's a whole magnitude less......
    – Pacerier
    Commented Jan 8, 2015 at 15:08
  • I agree with @Pacerier generally, but there can definitely be some "fun" to be had with naming major releases. However, my recommendation would be to name it something less insulting and something more inspiring. At least make it so that if the customer does find out, it instills confidence, not the lack thereof. For example, we are space nerds at CNTRAL so we named major releases after the up and coming SpaceX ships, like Falcon Heavy and Starship, etc. Was a nice way to look to the stars while looking at semi-colons and brackets all day. Commented Apr 3, 2021 at 17:44

Generation.Version.Revision.Build (9.99.999.9999)

Generation rarely changes. Only a big turn on product: DOS -> Windows, complete reengineering.

Version is for big incompatible changes, new functionality, changes on some specific paradigms on software, etc.

Revision is often done (minor features and bug fix).

Build is internal information.

  • Good idea. Where did you get the "generation" idea from?
    – Pacerier
    Commented Jan 8, 2015 at 7:17

git describe provides a nice extension to whatever numbering convention you've chosen. It's easy enough to embed this in your build/packaging/deployment process.

Suppose you name your tagged release versions A.B.C (major.minor.maintenance). git describe on a given commit will find the most recent tagged ancestor of the commit, then tack on the number of commits since then, and the abbreviated SHA1 of the commit:


If you're actually at one of the versions, of course, you'll just get the tag (1.2.3).

This has the nice benefit of letting you know exactly what source you built from, while not having to number every single build yourself.


Major.Minor.Public (build) [alpha/beta/trial], such as "4.08c (1290)"

  • With Major being the major version number (1, 2, 3...)
  • Minor being a 2 digit minor version (01, 02, 03...). Typically the tens digit is incremented when significant new functionality is added, the ones for bug fixes only.
  • Public being the public release of the build (a, b, c, d, e), which is often different from the minor version if a minor version is never released as a public update
  • build, being the actual build number that the compiler keeps track of.
  • with TRIAL, ALPHA, BETA X, or RC X appended for those special cases.

I prefer version numbers that assign some semantic meaning. As long as you can use the version number to track bugs reported with a particular version to changes that occurred in the source code (and in your activity management system) then you're probably using the right method.

I use .NET so I'm stuck with the .NET version numbering system but I try to give semantic meaning to the numbers so with


  • major = (up to the project)
  • minor = (up to the project)
  • build = build number from Hudson (you could use TeamCity or TeamBuild, etc. here)
  • revision = subversion or bazaar revision (depending on the project and what its using)

We always make sure thatt he version number is visible in some way (with our batch console-based programs its printed to console and a log file, with web apps its on the menu bar at the top usually)

This way if clients report problems we can use the version number to track if they are using the latest version and how many problems we have had with particular versions.

It's all about traceability!


Version numbers should have enough information that you avoid conflicts and fixing a bug in the wrong release type problems, but shouldn't convey additional information that isn't relevant.

For instance if you use the date customers can tell that they have an older version, and patches against old versions can have confusing versions.

I personally like semantic versioning:

  • Releases are Major.Minor.Patch
  • Patch increments every time you release a build.
  • Minor increments every time backwards compatible functionality is added.
  • Major increments when new functionality is not backwards compatible.
  • When Major == 0 you're in alpha/pre-release. Major >= 1 are your public releases.
  • Lower numbers reset to 0 every time you increment, so

    1.5.3 -> 1.5.4 (bug fix) -> 1.6.0 (minor feature) -> 2.0.0 (breaking change)

This way if someone is using, say, version 1.5.3 they could tell at a glance that they could upgrade to 1.5.4 to get the patches, that 1.6.0 would add functionality and that they shouldn't upgrade to 2.0.0 (at least without handling the change).

  • Semver only works for APIs. Not products.
    – Pacerier
    Commented Jan 8, 2015 at 7:18
  • @Pacerier could you explain why?
    – Keith
    Commented Mar 15, 2015 at 11:12
  • Per SemVer itself. You can't use SemVer without a public API.
    – Pacerier
    Commented Mar 19, 2015 at 15:20
  • @Pacerier that doesn't mean that you can't use this pattern for version numbering.
    – Keith
    Commented Mar 21, 2015 at 13:09

We use Major.Minor.Build#.YYMMDD[suffix], as we usually only do one production build on any particular day (but use a b/c/d suffix if there's more than one) and the YYMMDD gives users/customers/management an indication of the age of the build, where 6.3.1389 does not.

Major numbers increase with significant product features (paid-for).

Minor numbers increase with fixes/improvements (free update).

Build always increases; not all builds ship, so it's not a linear progression.

(public 1.0)  1.0.2-----
                |       \
              2.0.0    1.1.0
                |        |
              2.0.1    1.1.1 (public 1.1)
(public 2.0)  2.0.2-----
                |       \
              3.0.0    2.1.0
                       2.1.1 (public 2.1)

X.Y.Z is our internal version number. X.Y is the public version number, the one that has a meaning to our clients. When a X.Y.Z version becomes public, there will never be a X.Y.(Z+1) version : the public version is always the last of the serie.

X is incremented when a major version is released.

Y is used for the maintenance branches of those major releases, only for bug fixes.

Z is used internally, and has no fixed meaning. Until now, I create a new Z version when I think that the application has a set of features that are interesting to show to non developers, and is relatively stable. This way, I can show a demo of the "last known good version" of the application when someone ask one. In a near future, I plan to use the Z number versions for naming a "target" of features, in our bugtracker.

As a side note, we use maven (with the release command) to increment the version number. So, there are X.Y.Z-SNAPSHOT versions, too (which indicates any version between X.Y.(Z-1) and X.Y.Z).

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