Semver Comparator
100% LocalCompare semantic versions, check range satisfaction, and sort version lists.
v1.4.2 < v2.0.0
major changeVersion A
Version B
Enter two semantic versions to compare, or paste a list to sort. Range satisfaction checks included.
What is Semver Comparator?
Frequently Asked Questions
Technical Deep Dive
Semver Comparator
Compare two semantic version numbers (v1 vs v2), check if a version satisfies a range expression (^, ~, >=, hyphen ranges), and sort a list of versions in ascending order. Includes parsed component breakdown (major, minor, patch, pre-release) and a range syntax reference.
Compare, satisfy, sort
Diff two versions, test a version against a range (caret, tilde, hyphen, or ||), and sort a messy list into strict semver order.
Pre-release rules built in
Applies the real precedence rules — 1.0.0-beta.11 > 1.0.0-beta.2, normal > pre-release, build metadata ignored.
npm-range semantics
^0.2.3 narrows to >=0.2.3 <0.3.0, and ranges exclude pre-releases unless you opt in — the same logic npm uses.
Semantic Versioning: The Rule That Should Be Boring
Semantic Versioning (SemVer) is the most widely-adopted versioning scheme in software. It's a simple rule, increment MAJOR for breaking changes, MINOR for features, PATCH for fixes, that powers the dependency-resolution algorithms of npm, Cargo, Bundler, Composer, NuGet, and most other package managers. When everyone follows it, ecosystems work. When people don't, you get phantom regressions, broken builds, and 3am pager duty. This tool helps you parse, compare, and check ranges against version strings.
The Format
Example: 1.2.3-rc.1+sha.abc123
| Component | Meaning |
|---|---|
| MAJOR | Breaking change |
| MINOR | New feature, backward compatible |
| PATCH | Bug fix, backward compatible |
| PRERELEASE | Optional pre-release identifier (alpha, beta.1, rc.2) |
| BUILD | Optional build metadata (sha.abc123); ignored for ordering |
Rules:
- Each component is non-negative integer (no leading zeros).
- PRERELEASE can be dot-separated identifiers, each either numeric or alphanumeric.
- BUILD same format as PRERELEASE but ignored for comparison.
- Versions can never decrease, once released, never re-published.
Comparison Rules
To compare two versions:
- Compare MAJOR. Higher wins.
- If equal, compare MINOR. Higher wins.
- If equal, compare PATCH. Higher wins.
- If equal, normal (no PRERELEASE) > pre-release.
- If both pre-release, compare identifiers left-to-right:
- Numeric identifiers compared numerically.
- Alphanumeric compared lexically.
- Numeric < alphanumeric.
- Fewer identifiers < more identifiers (
1.0.0-alpha<1.0.0-alpha.1).
- BUILD ignored.
Examples (each row is ascending):
Note: beta.11 > beta.2 (numeric, 11 > 2), but alpha.beta > alpha.1 (alphanumeric vs numeric).
Range Expressions
npm-style ranges describe sets of acceptable versions. The operators:
| Operator | Meaning |
|---|---|
=1.2.3 or 1.2.3 |
Exact match |
>1.2.3 |
Greater than |
>=1.2.3 |
Greater than or equal |
<1.2.3 |
Less than |
<=1.2.3 |
Less than or equal |
!=1.2.3 |
Not equal (npm doesn't support this; some other tools do) |
^1.2.3 |
Compatible with 1.2.3 (allow MINOR + PATCH) |
~1.2.3 |
Approximately 1.2.3 (allow PATCH only) |
1.2.x or 1.2.* |
Wildcard PATCH |
1.x or 1.* |
Wildcard MINOR + PATCH |
* |
Any version |
1.2.3 - 1.4.0 |
Hyphen range, inclusive |
>=1.2.3 <2.0.0 |
Multiple constraints (intersected) |
| `>=1.2.3 \ | \ |
Caret (^) deep dive
^1.2.3 = >=1.2.3 <2.0.0. Compatible-with-1.2.3 in semver terms.
But special cases for pre-1.0:
^0.2.3=>=0.2.3 <0.3.0(treated as ~0.2.3).^0.0.3=>=0.0.3 <0.0.4(only this PATCH).
Reasoning: pre-1.0 versions are unstable; MINOR changes can break.
Tilde (~) deep dive
~1.2.3 = >=1.2.3 <1.3.0. Allows PATCH but not MINOR.
~1.2 = >=1.2.0 <1.3.0. Same as ~1.2.0.
~1 = >=1.0.0 <2.0.0. Same as ^1.0.0.
Pre-release matching
By default, ranges DON'T match pre-releases:
^1.2.3does NOT match2.0.0-beta.1.^1.2.3does NOT match1.2.3-rc.1.
To match pre-releases, the range itself must include a pre-release:
^1.2.3-rc.1matches>=1.2.3-rc.1 <2.0.0AND can match other pre-releases in 1.x.
This prevents accidentally getting an unstable version. If you want pre-releases, opt in explicitly: npm install pkg@beta or include pre-release in the range.
When to Bump Each Component
PATCH (1.2.3 → 1.2.4)
For backward-compatible bug fixes. Examples:
- Fix incorrect calculation.
- Fix typo in error message.
- Update internal dependency that doesn't affect API.
- Performance improvement.
- Documentation-only changes (some teams use PATCH; some don't bump at all).
MINOR (1.2.3 → 1.3.0)
For backward-compatible additions. Examples:
- Add new function/method.
- Add new optional parameter.
- Add new optional config option.
- Add new HTTP endpoint.
- Mark something deprecated (still works, will be removed in MAJOR).
MAJOR (1.2.3 → 2.0.0)
For backward-incompatible changes. Examples:
- Remove or rename public function.
- Change function signature (remove parameter, change types).
- Change return type/shape.
- Change default behavior.
- Drop support for older runtimes (Node 14 EOL, etc.).
- Remove deprecated APIs.
Less obvious breaks:
- Default value changes,
function f({ timeout = 5000 })→5000becomes30000. If users relied on the default, this breaks. - Error format changes, exception class name change can break catch blocks matching on class.
- Stricter input validation, previously-accepted inputs now error.
- Behavior changes in edge cases, caller might depend on undocumented behavior.
When in doubt, treat as breaking. Users prefer a needless MAJOR bump over a surprise break.
Pre-Release Versions
Use pre-releases for incremental rollouts:
In npm: npm publish --tag beta puts 1.0.0-beta under the beta tag. npm install pkg@beta installs the latest beta. npm install pkg still installs the latest stable.
Build Metadata
1.2.3+sha.abc123, the +sha.abc123 is build metadata, ignored for comparison. Used to identify which exact build produced a version (git SHA, CI build number).
Two versions differing only in build metadata are SAME version per semver. 1.0.0+a == 1.0.0+b.
In practice, npm doesn't use build metadata much; it's more common in non-npm package managers and Docker tags.
Lockfiles
package-lock.json, yarn.lock, Cargo.lock record the exact installed versions. They pin transitive dependencies too, A 1.2.3 might depend on B ^2.0.0; the lockfile records that B 2.5.7 was installed.
Lockfiles ensure reproducible builds across machines, time, and CI. Always commit them to source control (the npm best practice has evolved, old advice said don't commit for libraries, current advice says commit always).
If your install resolves differently than your lockfile expects, commands like npm ci (use lockfile strictly) vs npm install (update lockfile if compatible) behave differently.
Common Issues
Version conflicts: package A requires B ^1.0.0, package C requires B ^2.0.0. Resolver may install both versions (hoisting + nested). Sometimes causes runtime bugs ("Two copies of React detected"). Resolution: use peerDependencies for libraries that must share a version.
Phantom upgrade breaks: ^1.2.3 allows minor upgrades, but an upstream MINOR release contains a bug. Use ~ or lockfile to pin.
Pre-release confusion: ^1.2.3-rc.1 matches more pre-releases than expected. Be careful publishing pre-releases under a stable major.
0.x churn: project at 0.x has frequent breaking changes (allowed by spec). Either accept the churn or pin exact versions ("pkg": "0.5.2").
Outside npm
Other ecosystems use semver with variations:
- Cargo (Rust), strict semver. Caret is implicit.
- Bundler (Ruby),
~> 1.2.3means>=1.2.3 <1.3.0(like npm's~).~> 1.2means>=1.2 <2.0. - Composer (PHP), supports semver ranges with similar operators.
- NuGet (.NET), has its own range syntax:
[1.2.3,2.0.0). - Maven (Java), not semver by default but increasingly adopted.
- Go modules, strict semver with leading "v":
v1.2.3.
The semver spec is the same; the range syntax for picking versions varies.
Privacy
Parsing, comparison, and range matching run entirely in your browser. Version strings, sometimes encoding internal package names or unreleased version numbers, stay in the tab. Open DevTools Network during use: zero outbound requests.