By Tim King · Updated
SemVer Comparison Tool
Caret vs Tilde Ranges, Version Bumps and Sorting by Semantic Precedence
OneTask is free, with no sign-up, and built by one person.
If this tool saved you time, a coffee helps keep new ones coming.
How the SemVer Tool works
This semver comparison tool sorts and compares version numbers. Paste version numbers one per line and sort them in real precedence order, compare two of them, work out what the next major, minor, patch or prerelease should be, or test a list against a caret or tilde range. Prerelease and build metadata are handled by the specification's rules, not by string comparison.
Semver comparison tool: precedence rules
Semantic versioning is a contract expressed as three numbers. MAJOR.MINOR.PATCH says that a
patch bump fixes bugs without changing behaviour you rely on, a minor bump adds functionality
without breaking what already worked, and a major bump is permitted to break anything. The value is
entirely in consumers being able to trust it, which is why the mechanical rules matter.
Sorting versions as strings is wrong and the failure is quiet. Lexicographically 1.10.0 sorts
before 1.9.0, and 2.0.0-rc.2 sorts before 2.0.0-rc.10. Precedence is defined field by field
with each field compared as a number, which is what the sort above does — the difference only shows
up once you cross a version-ten boundary, by which point something is already picking the wrong
release.
A prerelease version is always lower than the release it precedes. 1.0.0-alpha comes before
1.0.0, because the prerelease tag marks something unfinished. Within prereleases, dot-separated
identifiers are compared one at a time: numeric identifiers compare numerically, alphanumeric ones
compare in ASCII order, and a numeric identifier always ranks lower than an alphanumeric one. That
last rule is why 1.0.0-alpha.1 beats 1.0.0-alpha.beta, which surprises most people the first
time they hit it.
Build metadata is ignored entirely when comparing. Anything after a plus sign — a commit hash,
a build number, a timestamp — carries no precedence at all, so 1.0.0+build.1 and 1.0.0+build.99
are equal versions. It exists to label an artefact, not to order it, and a release pipeline that
relies on build metadata to pick the newer of two builds is relying on something the specification
explicitly does not provide.
Zero-major versions play by looser rules and tooling knows it. While the major number is 0
the API is declared unstable, and package managers treat a caret range differently as a result:
^0.3.1 allows patch releases within 0.3 rather than everything below 1.0.0. Publishing a
library that stays on 0.x indefinitely means consumers never get the compatibility guarantee that
is the whole point of the scheme.
Caret and tilde differ by exactly one field. A caret range allows anything that does not change
the leftmost non-zero number, so ^1.4.0 accepts 1.9.2 but not 2.0.0. A tilde range pins the
minor version too, so ~1.4.0 accepts 1.4.7 but not 1.5.0. Caret is the usual default because
it collects compatible features automatically; tilde is the conservative option when a dependency
has a history of breaking things inside minor releases.
Bumping is not always an increment. Releasing 2.0.0-rc.1 as final is a major bump that
produces 2.0.0, not 3.0.0 — the prerelease was already standing in for that major. The bump
operations above follow the same rules the standard tooling does, so the number you get is the one
your package manager would have chosen.
FAQ
Why does 1.0.0-alpha sort before 1.0.0?
A prerelease tag marks a version as not yet the real release, and the specification defines it as
having lower precedence than the associated release. That is what makes 1.0.0-rc.1 a safe way to
publish a candidate without anyone's caret range picking it up.
What is the difference between ^1.2.3 and ~1.2.3?
The caret allows any release up to but excluding the next major, so 1.9.0 qualifies. The tilde
allows only patch releases within the same minor, so 1.2.9 qualifies but 1.3.0 does not.
Does build metadata affect which version is newer?
No. Everything after the plus sign is ignored for precedence, so two versions differing only in build metadata rank equally. Use the prerelease field if you need ordering.
What should I bump when I only changed documentation?
Nothing, if nothing shipped to consumers changed. If you are publishing a new artefact regardless, a patch bump is the conventional choice, since it signals no behavioural change.
How do I release a prerelease as final?
Bump the major, minor or patch that the prerelease was leading up to, which drops the prerelease
tag rather than incrementing the number again. 2.0.0-rc.3 becomes 2.0.0, not 3.0.0.
See also: all Dev Utilities tools, Formatters & Validators, Data & Encoding, Security & Identifiers, SEO, Accessibility, AI.
Related tools
HTTP Status Codes
Look up what any HTTP status code actually means.
Robots.txt Checker
Check a robots.txt file line by line before you deploy it.
CHMOD Calculator
Convert Unix permissions between rwx, octal and symbolic.
CSS Selector Tester
Test a CSS selector against pasted HTML and list every matching element.
Core Web Vitals Calculator
Check whether your page passes Core Web Vitals and which metric to fix first.