10aday › Version Constraint Checker › ~> vs ~= vs ~
~> vs ~= vs ~: the “pessimistic” operator in five package managersRubyGems (~>, the “pessimistic” or “twiddle-wakka” operator), pip (~=, “compatible release”) and Composer (~) share one rule:
the last number you wrote may increase, the ones before it are fixed. npm and Cargo use ~ differently: they always keep the minor number when you give one.
So the “same” constraint on 1.2 means <2.0 in three tools and <1.3 in the other two.
Have a constraint and a list of versions? Paste them into the Version Constraint Checker: it shows, side by side, what npm, Cargo, Composer, pip and RubyGems accept.
Each cell shows the operator that package manager uses, then the range it really allows. Highlighted: the two tools that read the two-number form differently.
| Constraint | RubyGems | pip | Composer | npm | Cargo | |
|---|---|---|---|---|---|---|
on 1 | ~> 1≥1.0.0 <2.0.0 | ~=1not valid | ~1≥1.0.0 <2.0.0 | ~1≥1.0.0 <2.0.0 | ~1≥1.0.0 <2.0.0 | try it |
on 1.2 | ~> 1.2≥1.2.0 <2.0.0 | ~=1.2≥1.2.0 <2.0.0 | ~1.2≥1.2.0 <2.0.0 | ~1.2≥1.2.0 <1.3.0 | ~1.2≥1.2.0 <1.3.0 | try it |
on 1.2.3 | ~> 1.2.3≥1.2.3 <1.3.0 | ~=1.2.3≥1.2.3 <1.3.0 | ~1.2.3≥1.2.3 <1.3.0 | ~1.2.3≥1.2.3 <1.3.0 | ~1.2.3≥1.2.3 <1.3.0 | try it |
on 0.2 | ~> 0.2≥0.2.0 <1.0.0 | ~=0.2≥0.2.0 <1.0.0 | ~0.2≥0.2.0 <1.0.0 | ~0.2≥0.2.0 <0.3.0 | ~0.2≥0.2.0 <0.3.0 | try it |
The “try it” links open the checker with the npm/Cargo/Composer spelling; type ~> 1.2 or ~=1.2 there to see RubyGems and pip.
| Constraint | npm | Cargo | Composer | pip | RubyGems | |
|---|---|---|---|---|---|---|
~> 1.2npm reads it as ~1.2 | ≥1.2.0 <1.3.0 | not valid | not valid | not valid | ≥1.2.0 <2.0.0 | try it |
~=1.2npm reads it as ~1.2 | ≥1.2.0 <1.3.0 | not valid | not valid | ≥1.2.0 <2.0.0 | not valid | try it |
~> 1.2.3, ~=1.2.3, ~1.2.3. All five tools agree: ≥1.2.3 <1.3.0.^1.2), and the two-number form in RubyGems and pip (~> 1.2, ~=1.2).
See tilde vs caret.~> 2.1 means ≥2.1 and <3.0; ~> 2.1.0 means ≥2.1.0 and <2.2. RubyGems drops the last number you wrote and bumps the one before it. It is called the pessimistic version constraint.
It is the PEP 440 compatible release operator. ~=1.4.2 means ≥1.4.2 and ==1.4.*; ~=1.4 means ≥1.4 and ==1.* (so <2.0). ~=1 is invalid: it needs at least two numbers.
Only with three numbers. ~=1.4.2 and npm ~1.4.2 both mean ≥1.4.2 <1.5.0. With two numbers they differ: pip ~=1.4 allows up to <2.0, npm ~1.4 stops before 1.5.0.
npm accepts ~> and reads it as its own tilde, so ~> 1.2 in package.json means ≥1.2.0 <1.3.0, not the RubyGems meaning (<2.0). Cargo and Composer reject ~>.
^ and ~ into [project] dependencies (Poetry 2, uv)