Semver Range Checker Online

Type an npm version range such as ^1.2.3, ~2.0 or >=1.0.0 <2.0.0 and see what it means in plain English, the comparators npm turns it into, and which versions it accepts. Paste a list of versions, or the output of npm view <pkg> versions --json, to see which ones match, why the others don’t, and which version npm install would pick. It is for anyone editing package.json, reviewing a dependency update, or wondering why npm won’t install the release a security scanner asked for.

The checker follows the same range rules as node-semver, the library npm uses, including the prerelease rule and the -0 upper bounds. It was tested against node-semver on millions of generated cases. Compare, Bump and Sort modes order versions by SemVer precedence and show what npm version would produce. Everything runs in your browser.

What it means

^1.2.3 means >=1.2.3 <2.0.0-0: any 1.x version from 1.2.3 up, but not 2.0.0.

bound includedbound excludedlisted version that matchesSpacing shows order, not distance.

  • ^1.2.3>=1.2.3 <2.0.0-0caret^ allows minor and patch updates, but never a new major version.
  • The -0 in <2.0.0-0 also rules out 2.0.0 prereleases such as 2.0.0-beta.1: -0 is the lowest prerelease there is.
  • Prereleases such as 1.2.4-beta.1 don't match, even inside the bounds, unless a comparator names a prerelease of the same version. Turn on Include prereleases to let them in.
npm install picks
1.9.9
Highest match
1.9.9
Lowest match
1.2.3

With no lockfile, npm installs the highest match, after first trying the version tagged latest if it is in the range. It passes over deprecated versions when it can.

2.0.0 is newer but outside ^1.2.3, so npm install and npm update won’t pick it. Only a wider range from whoever declares ^1.2.3, or an overrides entry in your package.json, brings it in. How ^ and ~ work

  • 1.2.2No matchBelow the range, which starts at 1.2.3
  • 1.2.3MatchesIn the range
  • 1.3.0MatchesIn the range
  • 1.9.9MatchesIn the range
  • 2.0.0-beta.1No matchAbove the range: <2.0.0-0 shuts out every 2.0.0 prerelease
  • 2.0.0No matchAbove the range, which stops before 2.0.0: ^ never moves to a new major version
Valid range>=1.2.3 <2.0.0-03 of 6 versions matchnpm install picks 1.9.9Processed locally

How to use it

  1. Type a range as it appears in package.json, or pick an example such as ^ caret or the minimatch fix, to see what it means.
  2. Paste versions to test, one per line or the output of npm view <pkg> versions --json, to see which match and which one npm would install.
  3. Switch to Compare, Bump or Sort to compare two versions, work out the next release, or order a list by precedence.

Related tools

JSON FormatterFormatJSON DiffFormatText Diff CheckerFormatGit Command BuilderDevOps

Next: format the output of npm view <pkg> --json in the JSON Formatter, or compare two versions of package.json in JSON Diff to see which ranges changed.

What this tool does

npm reads a dependency range in package.json by turning it into plain comparators. ^1.2.3 becomes >=1.2.3 <2.0.0-0, ~1.2.3 becomes >=1.2.3 <1.3.0-0, 1.x becomes >=1.0.0 <2.0.0-0, and 1.2.3 - 2.3.4 becomes >=1.2.3 <=2.3.4. The checker shows that form for every part of the range you type, explains each part, and draws the range on a version line. Each version you paste is tested the way npm tests it. Every comparator must pass in at least one || alternative. A prerelease such as 2.0.0-beta.1 matches only when a comparator in that alternative names a prerelease of the same major.minor.patch, unless you turn on Include prereleases. Each result says why: below the range, above it, the wrong exact version, or a prerelease the range skips. The highest match is what npm install picks when there is no lockfile, so the tool shows that too. Loose parsing reads ranges the way npm does, accepting =1.2.3 and ignoring tokens it can’t read. Compare explains which of two versions is higher and the release type between them. Bump lists every result of npm version, with --preid. Sort orders a list by precedence, as semver.sort does.

Example input and output

The minimatch case: a security fix in a new major
Input
Range: ^10.2.6
Versions: 10.2.4, 10.2.6, 11.0.1
Output
^10.2.6 means >=10.2.6 <11.0.0-0: any 10.x version from 10.2.6 up, but not 11.0.0.
10.2.4  no   Below the range, which starts at 10.2.6
10.2.6  yes  In the range
11.0.1  no   Above the range, which stops before 11.0.0: ^ never moves to a new major version
npm install picks: 10.2.6

A package that declares minimatch ^10.2.6 can never get 11.0.1, whatever you run. The package has to widen its range, or you can force the version with overrides in your own package.json. Load this with the minimatch fix example.

Caret on a 0.x version only allows patches
Input
Range: ^0.2.3
Versions: 0.2.3, 0.2.9, 0.3.0, 1.0.0
Output
^0.2.3 means >=0.2.3 <0.3.0-0: any 0.2.x version from 0.2.3 up, but not 0.3.0.
0.2.3  yes  In the range
0.2.9  yes  In the range
0.3.0  no   Above the range, which stops before 0.3.0: on 0.x, ^ allows patch updates only
1.0.0  no   Above the range, which stops before 0.3.0: on 0.x, ^ allows patch updates only
npm install picks: 0.2.9

SemVer says anything may change while the major version is 0, so npm treats the first non-zero part as the breaking one. ^0.0.3 goes further and allows only 0.0.3.

A prerelease needs a comparator that names it
Input
Range: ^2.0.0-beta.1
Versions: 2.0.0-beta.1, 2.0.0-beta.2, 2.0.0, 2.1.0-beta.1
Output
^2.0.0-beta.1 means >=2.0.0-beta.1 <3.0.0-0: any 2.x version from 2.0.0-beta.1 up, but not 3.0.0.
2.0.0-beta.1  yes  In the range: the range names a 2.0.0 prerelease
2.0.0-beta.2  yes  In the range: the range names a 2.0.0 prerelease
2.0.0         yes  In the range
2.1.0-beta.1  no   Prerelease of a different version: only 2.0.0 prereleases can match
npm install picks: 2.0.0

Opting in to one beta doesn’t opt you in to every later beta. 2.1.0-beta.1 is inside the bounds, but npm skips it because no comparator names a 2.1.0 prerelease.

Common errors and fixes

npm error notarget No matching version found for minimatch@^12.0.0.
No published version satisfies the range (code ETARGET). Paste the output of npm view minimatch versions --json under Versions to test to see which versions exist and where the range falls. Usually the range names a major that isn’t out yet, or only prereleases of it exist. It can also be a typo, or a registry that doesn’t have the package.
npm audit or a scanner wants a fix in a new major, and npm update doesn’t install it
npm update only moves within the ranges in package.json, including the ranges of the packages that depend on it, and ^ never crosses a major version. Check the declared range here against the fixed version. If it is outside, upgrade the package that declares the range, ask its maintainers to widen it, or pin the fix with overrides in your root package.json after testing that it works.
^0.2.3 doesn’t accept 0.3.0
That is by design. On 0.x, ^ allows patch updates only, because a 0.x minor release may break the API. Write ^0.3.0 or >=0.2.3 <0.4.0 if you have tested the newer version.
2.0.0-beta.1 doesn’t match >=1.0.0
A prerelease matches only when a comparator in the same alternative names a prerelease of that major.minor.patch, so nobody gets a beta by accident. Use >=2.0.0-beta.1 to opt in, or test with Include prereleases on, which is node-semver’s includePrerelease option. npm install doesn’t use that option.
Invalid tag name ">=1.2.3 && <2.0.0" of package "x@>=1.2.3 && <2.0.0": Tags may not have any characters that encodeURIComponent encodes.
npm treats a spec that isn’t a valid version or range as a dist-tag, and this one isn’t a valid range. Join comparators with a space (>=1.2.3 <2.0.0) and alternatives with ||. The checker points to the part it can’t read.
`npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync.
A range in package.json no longer accepts the version recorded in the lockfile, often after someone edited the range by hand. Check the range against the locked version here, then run npm install to update the lockfile and commit both files.

Common use cases

  • Checking whether a version a security advisory asks for is inside the range a dependency declares
  • Seeing which version npm install would resolve from the versions on the registry
  • Choosing between ^, ~ and an exact version when adding a dependency
  • Explaining 0.x caret ranges, hyphen ranges and || unions in a code review
  • Finding out why a beta or release candidate isn’t matched by a range
  • Working out the next version, and the npm version command, before a release

Privacy and security notes

  • Ranges and versions are parsed in this browser tab. Nothing you type is sent to DevPrix or to the npm registry. The tool never looks anything up, so paste the versions you want to test.
  • Share puts the range and the version list in the link’s #fragment, which browsers don’t send to servers. Anyone you send the link to sees the same check.

Frequently asked questions

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

^ allows any change that keeps the first non-zero number: ^1.2.3 accepts minor and patch updates up to, but not including, 2.0.0. ~ allows patch updates when you give a minor: ~1.2.3 stops before 1.3.0. With only a major, ~1 is the same as 1.x. npm install <pkg> saves a ^ range by default, because save-prefix defaults to ^.

Why doesn’t npm install the newest version that matches my range?

Because package-lock.json records exact versions. npm install uses them as long as they still satisfy the ranges in package.json. If a range no longer accepts the locked version, package.json wins and npm updates the lockfile. npm update moves packages to the newest version their ranges allow and leaves package.json alone unless you add --save.

What does the -0 in <2.0.0-0 mean?

-0 is the lowest prerelease there is, so <2.0.0-0 keeps out 2.0.0 and every 2.0.0 prerelease, such as 2.0.0-beta.1. node-semver writes ^ and ~ upper bounds this way so that a beta of the next major stays out, even when prereleases are allowed.

Is build metadata like +build.5 part of the comparison?

No. SemVer says build metadata must be ignored when working out precedence, so 1.2.3+build.5 satisfies the range 1.2.3, and npm strips +… from ranges before reading them. Sort mode still orders versions that differ only in build metadata by their build, as semver.sort does.

Does this match what npm itself does?

Yes, for valid ranges. The range rules follow node-semver, the library npm uses. The tool was checked against node-semver 7.8.5 and against the 7.7.4 copy bundled with npm 11, with no differences. npm install also checks the latest dist-tag first and passes over deprecated versions and ones whose engines don’t fit your Node.js, which a list of versions can’t show.

Do Cargo and Composer read ^ and ~ the same way?

Mostly, with one big exception. Cargo treats a bare version such as 1.2.3 as ^1.2.3, and its ^ and ~ match npm’s, including the 0.x rules. Composer’s ^ matches npm’s, but its ~1.2 means >=1.2 <2.0.0, where npm’s ~1.2 stops before 1.3.0. Both also accept commas between comparators, which npm doesn’t.

Guides