10aday › Version Constraint Checker › Tilde vs caret
Short answer: the caret ^ allows every update that does not change the first non-zero number;
the tilde ~ allows patch updates only, when you write a patch number. ^1.2.3 = ≥1.2.3 <2.0.0 and ~1.2.3 = ≥1.2.3 <1.3.0
in npm, Cargo and Composer alike. The trap is the two-number tilde: ~1.2 stops before 1.3.0 in npm and Cargo, but allows every 1.x from 1.2 in Composer.
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.
Highlighted cells are where the package managers disagree.
| Constraint | npm | Cargo | Composer | |
|---|---|---|---|---|
~1.2.3 | ≥1.2.3 <1.3.0 | ≥1.2.3 <1.3.0 | ≥1.2.3 <1.3.0 | try it |
~1.2 | ≥1.2.0 <1.3.0 | ≥1.2.0 <1.3.0 | ≥1.2.0 <2.0.0 | try it |
~1 | ≥1.0.0 <2.0.0 | ≥1.0.0 <2.0.0 | ≥1.0.0 <2.0.0 | try it |
~0.2.3 | ≥0.2.3 <0.3.0 | ≥0.2.3 <0.3.0 | ≥0.2.3 <0.3.0 | try it |
~0.2 | ≥0.2.0 <0.3.0 | ≥0.2.0 <0.3.0 | ≥0.2.0 <1.0.0 | try it |
^1.2.3 | ≥1.2.3 <2.0.0 | ≥1.2.3 <2.0.0 | ≥1.2.3 <2.0.0 | try it |
^1.2 | ≥1.2.0 <2.0.0 | ≥1.2.0 <2.0.0 | ≥1.2.0 <2.0.0 | try it |
^1 | ≥1.0.0 <2.0.0 | ≥1.0.0 <2.0.0 | ≥1.0.0 <2.0.0 | try it |
^0.2.3below 1.0: minor = breaking | ≥0.2.3 <0.3.0 | ≥0.2.3 <0.3.0 | ≥0.2.3 <0.3.0 | try it |
^0.2 | ≥0.2.0 <0.3.0 | ≥0.2.0 <0.3.0 | ≥0.2.0 <0.3.0 | try it |
^0.0.3only 0.0.3 releases | ≥0.0.3 <0.0.4 | ≥0.0.3 <0.0.4 | ≥0.0.3 <0.0.4 | try it |
^0.0 | ≥0.0.0 <0.1.0 | ≥0.0.0 <0.1.0 | ≥0.0.0 <0.1.0 | try it |
^0 | ≥0.0.0 <1.0.0 | ≥0.0.0 <1.0.0 | ≥0.0.0 <1.0.0 | try it |
1.2.3 (bare) | exactly 1.2.3 | ≥1.2.3 <2.0.0 | exactly 1.2.3 | try it |
Ranges shown for release versions. Pre-releases such as 1.3.0-rc.1 follow extra rules in each tool; see the
checker, which shows them.
^: “compatible with” — keep the leftmost non-zero number, let everything to its right move.~ in npm and Cargo: “approximately” — keep major and minor, let the patch move (with ~1, keep the major).~ in Composer: let the last number you wrote move. ~1.2 → any 1.x ≥ 1.2; ~1.2.3 → any 1.2.x ≥ 1.2.3.
This is the same rule as Ruby's ~> and pip's ~=: see ~> vs ~= vs ~.~1.2.3 accepts patch updates only (≥1.2.3 <1.3.0). ^1.2.3 also accepts minor updates (≥1.2.3 <2.0.0). npm writes ^ by default when you run npm install.
Below 1.0.0 the caret locks the first non-zero number. ^0.2.3 means ≥0.2.3 <0.3.0 and ^0.0.3 means ≥0.0.3 <0.0.4, in npm, Cargo and Composer.
No. In npm and Cargo ~1.2 means ≥1.2.0 <1.3.0. In Composer the last number you wrote may move, so ~1.2 means ≥1.2.0 <2.0.0. Write ~1.2.0 in Composer if you want patch updates only.
In Cargo a bare version is a caret requirement: serde = "1.2.3" means ^1.2.3 (≥1.2.3 <2.0.0). In npm and Composer the same string means exactly 1.2.3. Use =1.2.3 in Cargo to pin.
^ and ~ into [project] dependencies (Poetry 2, uv)