Check which versions match a semver range

Type a range such as ^1.2.3 and paste versions. See which match, why each one does or does not, and the range in plain English.

How it works

  1. Type a range such as ^1.2.3 or >=1.2.7 <1.3.0 || 2.x
  2. Paste the versions to test, one per line
  3. Read the table, the highest match and the plain-English explanation

What a range such as ^1.2.3 matches

The range ^1.2.3 matches every version from 1.2.3 up to, but not including, 2.0.0. In node-semver, the library npm uses, it expands to the comparators >=1.2.3 <2.0.0-0. The caret keeps the left-most non-zero number fixed. For ^1.2.3 that number is the major, so 1.2.4, 1.9.0 and 1.99.99 match while 2.0.0 and 1.2.2 do not. The table lists each version you paste, whether it matches, and which comparator accepted or rejected it. The highest matching version is shown as its own result, and the same list is available highest first so you can copy it.

Why ^0.2.3 and ^0.0.3 behave differently

A caret range only locks the left-most non-zero number, so versions below 1.0.0 are treated more strictly. ^0.2.3 means >=0.2.3 <0.3.0-0, because the 0 major is ignored and the minor, 2, is the one that stays fixed. ^0.0.3 means >=0.0.3 <0.0.4-0, so only 0.0.3 itself matches. Missing parts count as flexible: ^0.x is >=0.0.0 <1.0.0-0 and ^0.0 is >=0.0.0 <0.1.0-0. A tilde range is simpler. ~1.2.3 means >=1.2.3 <1.3.0-0, so only patch releases are accepted, and ~1 means >=1.0.0 <2.0.0-0. Hyphen ranges are inclusive, so 1.2.3 - 2.3.4 means >=1.2.3 <=2.3.4, and a partial upper end such as 2.3 allows everything inside 2.3.x.

How prereleases are handled

By default a prerelease such as 1.3.0-beta.1 is left out of a range unless one comparator in the same set names the same major, minor and patch with a prerelease tag. So ^1.2.3 does not match 1.3.0-beta.1 even though that version sorts between 1.2.3 and 2.0.0. The range >1.2.3-alpha.3 does match 1.2.3-alpha.7 but not 3.4.5-alpha.9. Turn on Include prereleases to compare prereleases like any other version; this matches the includePrerelease option of node-semver. The upper bounds that ranges expand to end in -0, such as <2.0.0-0, so 2.0.0-rc.1 stays outside ^1.2.3 even with the option on. A bound you type yourself, such as <2.0.0, does not get that -0.

Worked example

Take the range ^1.2.3 and the nine sample lines on the page. 1.2.3, 1.9.0 and v1.4.5 match, and 1.9.0 is the highest. 1.2.2 and 0.9.0 are below the lower bound. 2.0.0 and 2.0.0-rc.1 are not below the upper bound <2.0.0-0. 1.3.0-beta.1 fails the prerelease rule because the range names no prerelease of 1.3.0. The last line is not a version at all, so it is reported as invalid instead of being skipped. Build metadata such as +build.5 is ignored when comparing, as the semver rules say.

What this tool does not do

It follows the range grammar in the node-semver README, in its default strict mode. It does not read loose-mode ranges, other ecosystems' rules (Python, Ruby gems, Cargo and Maven each differ), or git, file and tag specifiers. It does not look up which versions of a package exist; you paste the list, for example from npm view. A range of more than 1,000 characters, more than 50 parts joined by ||, or more than 5,000 versions is refused with a message. Nothing you type leaves this tab.

Frequently asked questions

What does ^1.2.3 mean in package.json?

It means any version from 1.2.3 up to, but not including, 2.0.0, written as >=1.2.3 <2.0.0-0. npm may install 1.2.4 or 1.9.0 but never 2.0.0. The caret keeps the major number fixed when the major is 1 or higher.

What is the difference between ^ and ~ in semver?

The caret allows minor and patch updates, the tilde allows patch updates only. ^1.2.3 matches 1.9.0, ~1.2.3 does not: it stops before 1.3.0. With a tilde and no minor, ~1 allows any 1.x.y, the same as ^1.

Why does ^0.2.3 not match 0.3.0?

For versions below 1.0.0 the caret locks the first non-zero number, which is the minor in 0.2.3. So ^0.2.3 is >=0.2.3 <0.3.0-0. For ^0.0.3 the patch is locked too, and only 0.0.3 matches.

Why does my range not match 1.0.0-beta.1?

A prerelease only matches when a comparator in the same set names the same major.minor.patch with a prerelease tag. ^1.0.0 skips 1.0.0-beta.1, but >=1.0.0-beta.0 accepts it. Switch on Include prereleases to compare them like normal versions.

How do I write a range that matches 1.x or 2.x but not 3?

Join two parts with ||, for example ^1.0.0 || ^2.0.0, or write >=1 <3. A version matches when it satisfies every comparator in at least one part. The table names the part that accepted each version.

Are the versions I paste uploaded?

No. The text is processed in your browser and not uploaded. The range and the versions are not stored; only the two settings, Include prereleases and the table filter, are saved on this device.