Also available in: Español · Português · Français · العربية
Semver checker
Whether a version satisfies a range, the comparators the range really expands to, and a straight answer when a pre-release is refused.
What is semantic versioning?
Semantic versioning is the convention that a version number is three numbers with meaning: major.minor.patch. Increase the patch for a fix that changes nothing else, the minor for something added compatibly, and the major when existing code will break. A hyphen introduces a pre-release — 2.0.0-rc.1 — and a plus introduces build metadata that is ignored entirely when comparing.
The specification at semver.org defines that format, and it defines precedence: which of two versions is newer, including the rule that a pre-release always sorts below the release it precedes. 1.0.0-alpha comes before 1.0.0, not after it.
What the specification does not define is ranges. Search its text for caret, tilde or range and you will not find them. The ^ ~ || and x-range syntax that every package manifest is full of comes from npm, and this page checks a version against it — while being clear about which half is the standard and which half is a convention on top of it.
How to use it
- Put a version in the first box and a range in the second. 1.2.4 against ^1.2.3, or a pre-release like 1.2.4-beta.1, or a range as complicated as >=1.2.0 <2.0.0 || ^3.
- Read the expansion, not just the verdict. Every range becomes plain comparators before anything is compared, and each one is shown with whether it holds. A surprising answer is usually obvious once the bounds are written out.
- Try the pre-release toggle if a beta is being refused. It shows what changes — and it changes the range itself, not only the comparison.
The caret means three different things
The caret is described as “compatible with”, which is fine until you notice it behaves differently depending on which leading number is zero. ^1.2.3 allows anything up to but not including 2.0.0. ^0.2.3 allows only patch releases, stopping at 0.3.0. And ^0.0.3 allows nothing at all beyond 0.0.3 itself.
That is deliberate — before 1.0.0 the convention is that anything may break, so the caret tightens to compensate. The consequence is one people rarely expect: below 1.0.0, ^0.2.3 and ~0.2.3 are the same range. The distinction everyone relies on between “allow minor updates” and “allow patch updates” simply disappears, because there is no minor update the caret would allow.
One more detail visible in the expansion above: the upper bounds are written <2.0.0-0 rather than <2.0.0. Without that trailing -0, a pre-release of the next major — 2.0.0-rc.1 — would sort below 2.0.0 and slip through a range that was supposed to stop before it.
Why your beta does not match
This is the question that brings most people to a semver checker, and the usual explanation is not quite right. A pre-release version is excluded from a range even when it sits comfortably inside the bounds: 1.2.4-beta.1 satisfies both >=1.2.3 and <2.0.0-0, and is still refused by ^1.2.3.
The rule is often stated as “unless the range itself mentions a pre-release”, and that is too loose. What is required is that some comparator in the range carries the same major.minor.patch. So 1.2.4-beta.1 is still refused by ^1.2.3-alpha — that range does name a pre-release, but on 1.2.3, and the version being tested is 1.2.4. Change the version to 1.2.3-beta.1 and it is accepted.
The reasoning behind it is that a pre-release of 1.2.4 has not been promised to behave like 1.2.4, so opting into a range should not silently opt you into unreleased code for versions you never named. When you do want it, the pre-release toggle is the escape hatch — and it is worth knowing that it changes how the range is built rather than how it is compared. Under it, ^1 becomes >=1.0.0-0, while ^1.0.0 stays >=1.0.0, because only a bound that was filled in from a partial version gets lowered.
Honest limits
This checks version strings against range strings and nothing else. It does not know what is published, so it cannot tell you which version a range would actually install today, and it cannot tell you whether an upgrade will break your code — semantic versioning is a promise made by a publisher, not a guarantee anyone verifies. A major release that changes nothing you use is harmless; a patch release can still break you.
The range grammar implemented here is npm's, which is by far the most common but not the only one. Other ecosystems use different spellings for similar ideas, and a range copied from one of those will either be rejected here or, worse, mean something different. Ranges with npm-specific extras that reach outside the version grammar — a git URL or a local path in place of a version — are not ranges in this sense and are not handled.
Because that grammar has no specification, the correctness standard here is agreement with the reference implementation rather than conformance to a document. The engine is checked against it over 1,680 version-and-range pairs with no disagreements, and separately against the specification's own precedence rules, which do exist.
Why is it free?
Because it costs nothing to run. The parsing and comparison happen in your browser; no version, range or manifest is uploaded, and there is no account.
The precedence rules come from the specification and the range grammar from the implementation that defines it in practice, with the tests committed alongside the code.