SemVer validator
Validate semantic versions and parse ranges.
Version
- MAJOR
- MINOR
- PATCH
- Prerelease
- Build metadata
Range
JSON result
What counts as a version
Strict SemVer 2.0.0 grammar. The three numbers are non-negative ASCII integers without leading zeros.
- MAJOR.MINOR.PATCH
- breaking / compatible / fixed
- 1.2.3-alpha.1
- prerelease, ranks below 1.2.3
- 1.2.3+build.5
- build metadata, ignored for precedence
- 1.2.3-0.3
- numeric prerelease identifiers are compared as numbers
- v1.2.3
- not a semantic version (spec FAQ)
- 01.2.3
- not valid: leading zero
- 1.2.3-01
- not valid: zero-padded numeric prerelease
- 1.2.3+0.09
- valid: build metadata may be zero-padded
Range operators
- 1.2.3
- exactly this version
- ^1.2.3
- compatible: >=1.2.3 <2.0.0-0
- ~1.2.3
- patch only: >=1.2.3 <1.3.0-0
- >=1.2.3 <2.0.0
- AND of comparators in one set
- 1.2.3 - 2.0.0
- inclusive range, spaces required on both sides
- 1.2.x / 1.x / *
- partial versions and wildcards
- a || b
- union: either set may match
- ~>1.2.3
- npm historical alias, handled as ~1.2.3
How npm fills in partial versions
Verified against node-semver; the -0 suffix is npm sentinel that excludes prereleases of the next series.
| Range | Expanded |
|---|---|
| ^1.2.3 | >=1.2.3 <2.0.0-0 |
| ^0.2.3 | >=0.2.3 <0.3.0-0 |
| ^0.0.3 | >=0.0.3 <0.0.4-0 |
| ^1 | >=1.0.0 <2.0.0-0 |
| ~1.2.3 | >=1.2.3 <1.3.0-0 |
| ~1.2 | >=1.2.0 <1.3.0-0 |
| ~1 | >=1.0.0 <2.0.0-0 |
| 1.2.x | >=1.2.0 <1.3.0-0 |
| 1.x | >=1.0.0 <2.0.0-0 |
| 1.2.3 - 2.0.0 | >=1.2.3 <=2.0.0 |
| 1.2.3 - 2 | >=1.2.3 <3.0.0-0 |
| >1.x | >=2.0.0 |
Prerelease precedence
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
Numeric identifiers compare as numbers and rank below alphanumeric ones; a shorter prefix ranks lower. Build metadata never matters.
Common mistakes
These paste straight out of package.json and chat logs.
- "1.2.3",
- The quotes and comma came along from package.json - paste the version only.
- v1.2.3
- Git tags carry a v, semantic versions do not.
- 1.2
- Two numbers are a range, not a version.
- 1.2.3-01
- npm loose mode reads it as 1.2.3-1 and silently rewrites it.
Which rule book is used
- The verdict on a version string is strict SemVer 2.0.0 - no loose mode, no rewriting, no normalising.
- Ranges follow npm node-semver, because the SemVer spec does not define ranges.
- This tool is stricter than npm on ranges: a v prefix or a leading zero inside a range is rejected, and an empty side of || is an error rather than "any version".
- The npm readings shown for an invalid version come from semver.valid(v, {loose:true}) and semver.coerce(v). They are information only - never a pass.
- Positions count code points and start at 1 in the interface, at 0 in the JSON.
How to use it
- Paste a version such as 1.2.3-beta.1+build.5 into the left field. Everything below updates as you type - there is no button to press.
- Optionally paste an npm range such as ^1.2.0 on the right to see how the version and the range relate.
- Read the badge first: valid or not, and if not, which rule broke at which character.
- Tick Include prerelease when you want the npm includePrerelease reading of the range.
- Expand JSON result to copy or download the full issue list.
Worked example
Version + range
1.2.3-beta.1+build.5 ^1.2.0
Result
Valid SemVer (MAJOR 1, MINOR 2, PATCH 3, prerelease beta.1, build build.5). ^1.2.0 expands to >=1.2.0 <2.0.0-0, bounds [1.2.0, 2.0.0). Verdict: not satisfied - the set has no prerelease comparator for 1.2.3.
Tick Include prerelease and the same pair becomes satisfied.
Limitations
- The verdict is strict SemVer 2.0.0, so v1.2.3 and 1.2.3-01 are rejected even though npm loose mode accepts or rewrites them.
- Ranges follow npm node-semver only - git describe, Cargo, PEP 440 and Go module versions are out of scope.
- No registry lookups: the tool cannot tell you which version ^1.2.0 would actually install.
- One version and one range at a time - no batch lists, no sorting, no pairwise comparison, no bump preview.
- Core numbers above Number.MAX_SAFE_INTEGER are flagged and compared as text, never converted to a JS number.
- Nothing leaves the page: no network, no storage, no URL parameters - a reload clears everything.
Related tools
More developer helpers that run entirely in your browser.