By · Updated

SemVer Comparison Tool

Caret vs Tilde Ranges, Version Bumps and Sorting by Semantic Precedence

No ratings yet

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