10aday › Version Constraint Checker › ~> vs ~= vs ~

~> vs ~= vs ~: the “pessimistic” operator in five package managers

RubyGems (~>, 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.

The same intent, five spellings

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.

ConstraintRubyGemspipComposernpmCargo
on 1~> 1
≥1.0.0 <2.0.0
~=1
not 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.

Cross-checks you can rely on

ConstraintnpmCargoComposerpipRubyGems
~> 1.2
npm reads it as ~1.2
≥1.2.0 <1.3.0not validnot validnot valid≥1.2.0 <2.0.0try it
~=1.2
npm reads it as ~1.2
≥1.2.0 <1.3.0not validnot valid≥1.2.0 <2.0.0not validtry it

Which one should I write?

Common questions

What does ~> mean in a Gemfile?

~> 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.

What does ~= mean in requirements.txt?

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.

Is pip ~= the same as npm ~?

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.

Can I write ~> in package.json?

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 ~>.

Related

Sources