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.

closed as primarily opinion-based by gnat, user40980, GlenH7, Dan Pichelman, Corbin March Sep 8 '13 at 22:27

Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise. If this question can be reworded to fit the rules in the help center, please edit the question.

13 Answers 13


I find myself rarely agreeing completely with Jeff Atwood, but I tend to follow his 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. – luis.espinal Oct 16 '10 at 12:09
  • 1
    How does/should "build number" relate to "changeset identifier (hash)"? Is it part of the hash, incremental, or something else? – Jace Browning Jul 23 '13 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 Feb 8 '15 at 21:37
  • If you call ToString() on a .NET Version structure the build will be the 3rd number, not the revision. As you can see with this powershell script: $version = New-Object System.Version 1, 2, 3, 4; $version.ToString(); $version.Build; – Joel McBeth Sep 3 '15 at 15:48
  • Does "build number" imply that it's just minor tweaks like bug fixes? Should any new functionality at least get its own revision number? – Kyle Delaney Apr 5 '17 at 14:44

Semantic Versioning (http://semver.org/) 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. – Mark Canlas Jan 19 '12 at 17:48
  • I was a little late to the party... I added this answer 9 months after the original question. ;-) – M. Dudley Jan 19 '12 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 Oct 9 '12 at 23:59
  • @MarkCanlas doesn't get more love because it attaches specific ideas to what constitutes a major/minor/patch release. It talks about APIs which is kinda...weird – Rudolf Olah Jul 5 '13 at 16:54
  • 5
    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 Apr 1 '14 at 16:18

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 Sep 14 '10 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 Nov 13 '10 at 2:38
  • 5
    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 Dec 17 '10 at 21:41
  • 1
    @jkerian, why does compatibility matter for this? – AviD Jan 3 '11 at 10:30
  • 12
    @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 Jan 3 '11 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.
  • 2
    This is essentially known as Semantic Versioning : semver.org – Patrice M. Oct 31 '13 at 10:52
  • 2
    @PatriceM. Thanks for sharing that link. semver.org didn't exist when I wrote that answer. – Ken Bloom Oct 31 '13 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 and SCMFViz application illustrating basic principles of version numbering 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.

  • First link down............... – Pacerier Jan 8 '15 at 7:11

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.

  • 2
    Seems like an inefficient use of time and energy............. – Pacerier Jan 8 '15 at 7:16
  • 10
    So was leaving that comment, but it didn't stop you. – Jesse C. Slicer Jan 8 '15 at 12:46
  • It's a whole magnitude less...... – Pacerier Jan 8 '15 at 15:08

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 Jan 8 '15 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!


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.


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 Jan 8 '15 at 7:18
  • @Pacerier could you explain why? – Keith Mar 15 '15 at 11:12
  • Per SemVer itself. You can't use SemVer without a public API. – Pacerier Mar 19 '15 at 15:20
  • @Pacerier that doesn't mean that you can't use this pattern for version numbering. – Keith Mar 21 '15 at 13:09
(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.