Guide
Semantic versioning: what caret, tilde and ranges really allow
A dependency written as ^4.17.21 in a package file looks precise and still leaves a lot open: which versions will actually be installed? Semantic versioning gives each part of a version number a meaning, and range operators build on that meaning. This page spells the operators out, lets you test them against real version lists, and does the arithmetic for the next release number.
Precedence
A version has three numbers, MAJOR.MINOR.PATCH, compared from left to right as numbers. A pre-release suffix, as in 2.0.0-beta.1, makes a version older than the same version without it, and pre-release identifiers are compared piece by piece, numbers numerically and words alphabetically. Build metadata after a plus sign, such as 1.0.0+build5, is ignored when comparing, as the specification says. So 1.0.0-beta.1 < 1.0.0, and 1.10.0 > 1.9.0.
Range operators
A caret allows changes that do not touch the leftmost non-zero part, so ^1.2.3 means at least 1.2.3 and below 2.0.0. A tilde allows patch-level changes: ~1.2.3 means at least 1.2.3 and below 1.3.0. An x-range such as 1.x or 1.2.x stands for any version in that series. A hyphen range 1.2.3 - 2.3.4 means at least the first and at most the second. A space joins comparators that must all hold, as in >=1.0.0 <2.0.0, and || separates alternatives that may hold. The page shows each range after expansion.
The zero rule and pre-releases
Versions under 1.0.0 are treated as unstable, so ^0.2.3 allows only 0.2.3 up to below 0.3.0, and ^0.0.3 allows exactly 0.0.3. For pre-releases, a range excludes them unless a comparator mentions a pre-release of the same MAJOR.MINOR.PATCH. So ^1.2.3 does not include 1.3.0-rc.1, even though 1.3.0-rc.1 is arithmetically between 1.2.3 and 2.0.0; the table gives that reason in the “Why” column. The option “Include pre-releases” switches the rule off, like npm’s flag of the same purpose.
Bumping and comparing
In “Next version”, enter the current version and choose what to raise. Minor from 1.4.2 gives 1.5.0, as the lower parts reset. The pre-release choices add a label: prerelease with the label “beta” on 1.4.2 gives 1.4.3-beta.0, on 1.4.2-beta.1 gives 1.4.2-beta.2, and premajor with “rc” gives 2.0.0-rc.0. The compare tool takes two versions and says which is newer or whether they have the same precedence.
A worked example
The Sample button loads the range ^1.2.3 and eight versions. The page normalises the range to >=1.2.3 <2.0.0-0 and reports 1.2.3 as the lowest allowed version. 1.2.3, 1.2.9 and 1.9.0 fit, with 1.9.0 the highest. 1.0.0, 0.9.5 and 2.0.0 are outside the range, 2.0.0-beta.1 is below 2.0.0 and so also outside, and 1.3.0-rc.1 is excluded because it is a pre-release. For ~1.2.3 the normalised range is >=1.2.3 <1.3.0-0, so 1.2.9 fits and 1.3.0 does not.
Limits
The rules are those of npm’s node-semver. Python’s PEP 440, Maven, Ruby gems and Go modules use different syntax and sometimes different precedence, so a result here does not carry over. Only versions that parse as MAJOR.MINOR.PATCH are tested; loose mode accepts a leading v and an equals sign. The page does not look up packages or registries, so it cannot tell which versions exist.
Related tools
- Glob Tester checks file patterns, another matching language in build files.
- Regex Tester tests regular expressions.
- Diff Checker compares two lock files or manifests.
- JSON Formatter tidies package manifests before you edit them.
Checked against the current version of the SemVer Calculator on .

