The same string, five readings. ~1.2 stops below 1.3 in npm and Cargo but below 2.0 in Composer. ~>1.2 stops below 1.3 in npm but below 2.0 in RubyGems. A bare 1.2 is 1.2.x in npm, below 2.0.0 in Cargo, exactly 1.2.0 in Composer and RubyGems, and not a valid specifier in PEP 440. Each ecosystem is following its own published or implemented grammar. This page runs a port of each one, offline.
Each cell shows how that ecosystem parses the literal line, whether it matches the requirement, and whether the ecosystem's default policy would admit it. A row marked on the left gets different answers across the valid columns.
Pick a source ecosystem. If its reading reduces to one interval (an optional lower bound and an optional upper bound), the page writes that interval in each target's plain comparator syntax, then re-reads every emitted string with the target's own engine against your test versions. The live agreement count is the only claim. No emitted form is claimed to be exactly equivalent.
Runs on load. Expected values were produced by the real engines and by the upstream test suites, then frozen into this page. The count below is computed now, in your browser.
| Grammar | Comma | Whitespace | OR | Hyphen range | Pre-release: matches the requirement | Pre-release: admitted by default |
|---|---|---|---|---|---|---|
| npm | Refused | AND | || | Yes | Only if a comparator with the same major.minor.patch carries a pre-release | Same as the match |
| Cargo | AND (required) | Refused between comparators | Refused | No | Same rule as npm | Same as the match |
| Composer | AND | AND | || or | | Yes | Matching ignores stability, so >=1.2 matches 1.3.0-RC1 | Held back by minimum-stability, which defaults to stable. A stability flag such as @beta overrides it. In a root requirement, a single-token constraint that names a pre-release, such as ^1.2.3-beta.2, sets that flag by itself |
| PEP 440 | AND | Refused between clauses | Refused | No | Exclusive comparisons have extra rules (<1.5 refuses 1.5.0rc1) | Depends on the candidate set: pre-releases are kept only when no final or post release matches, or when a specifier names a pre-release |
| RubyGems | Separate requirement strings (this page splits on commas) | Refused between comparators | Refused | No | Gem::Requirement#satisfied_by? admits pre-releases | Gem::Dependency#match? excludes them unless the requirement names one |
PEP 440 notes: already-installed pre-releases are not modelled. The --pre box above models an explicit user request. Composer notes: this page models the default minimum-stability, explicit @ stability flags, and the flag Composer infers when a root requirement names a pre-release in a single-token constraint (^1.2.3-beta.2 admits beta and above). It reads the range as your own composer.json require; a dependency's requirements get no inferred flag.