Semantic version compare, sort and npm range checker

Test npm ranges (^, ~, x, ||, hyphen) with reasons, compare, sort and bump versions.

Examples: ^1.2.3, ~1.4, >=2.0.0 <3, 1.2 - 2.3, 1.x || >=3.0.0-beta.1

Paste the list from npm view <package> versions, a changelog or your tags.

Off by default: a pre-release only matches a range that mentions a pre-release of the same x.y.z.

Means >=1.2.3 <2.0.0-0

Highest matching version: 1.9.9

VersionSatisfiesWhy
1.2.3 yespasses >=1.2.3 <2.0.0-0
1.2.10 yespasses >=1.2.3 <2.0.0-0
1.3.0-beta.1 nopre-release, and ^1.2.3 names no pre-release of 1.3.0
1.9.9 yespasses >=1.2.3 <2.0.0-0
2.0.0-rc.1 nofails <2.0.0-0
2.0.0 nofails <2.0.0-0
v1.4.0 yespasses >=1.2.3 <2.0.0-0
1.02.0—invalid: numbers may not have leading zeros

What this tool does

Four tabs for working with version numbers:

  • Range check: type an npm range and a list of versions. Each version is marked as matching or not, with the reason: which comparator it passes or fails, or that a pre-release was left out by npm's pre-release rule. The tool shows what the range really means (^1.2.3 is >=1.2.3 <2.0.0-0) and the highest version in your list that matches, which is what npm install would pick.
  • Compare two: which of two versions is higher, and which part decides it.
  • Sort a list: SemVer order, lowest or highest first, with invalid entries listed and explained.
  • Bump: the next version for each of npm's release types (major, minor, patch, premajor, preminor, prepatch, prerelease), with an optional identifier such as rc.

Everything follows the Semantic Versioning 2.0.0 specification and npm's own range rules (node-semver). The tests check the ordering example from semver.org, about a hundred of node-semver's own include and exclude fixtures, and 20,000 random ranges against node-semver itself (in its default mode).

Precedence in brief

A version is MAJOR.MINOR.PATCH, optionally followed by - and a pre-release, and + and build metadata. Compare major, minor and patch as numbers (1.10.0 is above 1.9.0). A pre-release is lower than the release it leads to: 1.0.0-rc.1 < 1.0.0. Pre-release identifiers compare left to right: numbers numerically, text in ASCII order, and a number is lower than text; if all compared parts are equal, the shorter list is lower. So the spec's own example sorts as 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0. Build metadata (+20261014) is ignored for precedence. Leading zeros (1.02.0) are invalid.

npm ranges in brief

  • Caret ^ allows changes that do not touch the left-most non-zero number: ^1.2.3 means >=1.2.3 <2.0.0, ^0.2.3 means >=0.2.3 <0.3.0, and ^0.0.3 means only 0.0.3 and its pre-releases.
  • Tilde ~ allows patch changes: ~1.2.3 means >=1.2.3 <1.3.0; ~1 means >=1.0.0 <2.0.0.
  • X-ranges 1.x, 1.2.* and partial versions such as 1.2 fill in the missing parts.
  • Hyphen 1.2 - 2.3.4 means >=1.2.0 <=2.3.4; a partial upper end such as - 2.3 means <2.4.0.
  • Comparators separated by spaces must all match; sets separated by || are alternatives.

The pre-release rule surprises everyone once: by default ^1.2.3 does not match 1.3.0-beta.1, even though 1.3.0-beta.1 is between 1.2.3 and 2.0.0. A pre-release only matches a range that names a pre-release of the same major.minor.patch, so ^1.3.0-beta.0 would match it. Tick "Include pre-releases" to get npm's --include-prerelease behaviour.

Why this matters

Your package.json says ^4.17.0, the lock file says 4.17.21, and a teammate gets 4.18.0 after a fresh install: that is the caret at work. Reading a range correctly tells you what a fresh install can pull in, and the bump tab tells you which number to change when you publish. The article semantic versioning, caret and tilde ranges explained walks through real upgrade decisions. To check a package.json, the JSON formatter validates it; to compare two lock files, use the diff checker.

Frequently asked questions

What is the difference between ^ and ~ in package.json?

^1.2.3 accepts any 1.x.x from 1.2.3 up (new minor and patch versions); ~1.2.3 accepts only 1.2.x from 1.2.3 up (patch versions). For 0.x versions the caret is stricter: ^0.2.3 stays below 0.3.0.

Why doesn't ^1.2.3 match 1.3.0-beta.1?

npm excludes pre-releases unless the range mentions a pre-release of the same major.minor.patch. Use ^1.3.0-beta.0 or --include-prerelease to opt in.

Is 1.0.0-beta.11 higher than 1.0.0-beta.2?

Yes. Numeric identifiers are compared as numbers, so 11 > 2. Text identifiers are compared character by character, which is why beta.11 sorts correctly but beta11 would not.

Does build metadata affect the order?

No. 1.0.0+build.1 and 1.0.0+build.2 have the same precedence; only the part before + counts.

Is a leading v allowed?

Not in SemVer itself, but npm accepts and strips it, and so does this tool: v1.2.3 is read as 1.2.3. Leading zeros such as 1.02.0 are always invalid.