How can I compare arbitrary version numbers?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Comparing version numbers sounds simple until you run into inputs like 1.2, 1.2.0, 2.0-rc1, or 2024.10.15. The right comparison rule depends on the versioning scheme, but most practical solutions follow the same pattern: split the version into meaningful parts, compare numeric pieces numerically, and compare pre-release markers with explicit rules.
Start With the Versioning Rules
Before writing code, decide what counts as the same version and what counts as newer. For example:
- Is
1.2the same as1.2.0? - Is
1.0-rc1older than1.0? - Does build metadata affect precedence?
If your project follows Semantic Versioning, the rules are already defined. If your versions are arbitrary internal strings, you need to define the rules yourself instead of relying on guesswork.
Numeric Segment Comparison
The simplest case is dotted numeric versions. Split on dots, convert segments to integers, and compare left to right.
This already handles two important cases correctly:
- '
2.10is greater than2.2because10 > 2' - trailing missing numeric segments are treated as zero
Handling Pre-Release Labels
Pre-release labels such as alpha, beta, and rc should not be compared with naive string ordering alone. You need a rule set.
One common convention is:
- final release is newer than any pre-release of the same numeric version
- '
alpha < beta < rc < final'
Here is a simple comparison function for versions shaped like 1.2.0 or 1.2.0-rc1:
This is not a full SemVer implementation, but it shows the structure clearly.
Prefer Existing Parsers When the Ecosystem Has One
If you are comparing versions from a real package ecosystem, using the ecosystem's parser is safer than inventing your own. Python packages, NuGet packages, Maven artifacts, and OS package managers may all have slightly different precedence rules.
That matters because "arbitrary version numbers" is really a requirements question. Two teams may both say "compare versions" while meaning different ordering semantics.
Common Pitfalls
One common mistake is comparing version strings lexicographically. That makes 2.10 look smaller than 2.2, which is wrong for numeric version semantics.
Another issue is silently treating pre-release tags as plain suffix text without deciding how they rank against final releases.
It is also easy to ignore trailing zeros. Many systems consider 1.2 and 1.2.0 equivalent, but a naive segment-by-segment comparison can mis-handle that if you do not normalize lengths.
Summary
- Version comparison needs explicit rules before you write code.
- Numeric segments should be compared numerically, not as plain strings.
- Trailing missing segments are often treated as zeros.
- Pre-release labels need defined precedence rather than ad hoc string comparison.
- If the version source already has a standard parser, use it instead of inventing a new one.

