10aday › Version Constraint Checker › Composer version constraints
~1.2, ^1.2, 1.2.* and "1.2" really allow in composer.jsonShort answer: in composer.json, ^1.2.3 allows ≥1.2.3 <2.0.0 (like npm). The tilde lets the last number you wrote move:
~1.2 = ≥1.2.0 <2.0.0, ~1.2.3 = ≥1.2.3 <1.3.0. A bare version is exact, even a partial one: "1.2" means 1.2.0 only.
Those last two rules are where people coming from npm get surprised.
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: npm reads the same string differently.
| Constraint | Composer | npm | |
|---|---|---|---|
"1.2.3" (bare) | exactly 1.2.3 | exactly 1.2.3 | try it |
"1.2" (bare)Composer: exactly 1.2.0 | exactly 1.2.0 | ≥1.2.0 <1.3.0 | try it |
~1.2.3 | ≥1.2.3 <1.3.0 | ≥1.2.3 <1.3.0 | try it |
~1.2 | ≥1.2.0 <2.0.0 | ≥1.2.0 <1.3.0 | try it |
~1 | ≥1.0.0 <2.0.0 | ≥1.0.0 <2.0.0 | try it |
~0.3 | ≥0.3.0 <1.0.0 | ≥0.3.0 <0.4.0 | try it |
^1.2.3 | ≥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 | try it |
^0.3below 1.0: minor = breaking | ≥0.3.0 <0.4.0 | ≥0.3.0 <0.4.0 | try it |
^0.0.3 | ≥0.0.3 <0.0.4 | ≥0.0.3 <0.0.4 | try it |
1.2.* | ≥1.2.0 <1.3.0 | ≥1.2.0 <1.3.0 | try it |
1.* | ≥1.0.0 <2.0.0 | ≥1.0.0 <2.0.0 | try it |
* | any version | any version | try it |
>=1.2 <2.0 | ≥1.2.0 <2.0.0 | ≥1.2.0 <2.0.0 | try it |
>=1.2,<2.0npm has no comma | ≥1.2.0 <2.0.0 | not valid | try it |
>1.2 | >1.2.0 | ≥1.3.0 | try it |
!=1.2.3 | not 1.2.3 | not valid | try it |
1.2 - 2.3 | ≥1.2.0 <2.4.0 | ≥1.2.0 <2.4.0 | try it |
^1.2 || ^3.0 | ≥1.2.0 <2.0.0 or ≥3.0.0 <4.0.0 | ≥1.2.0 <2.0.0 or ≥3.0.0 <4.0.0 | try it |
Ranges shown for stable releases. Composer also filters by stability (minimum-stability, @dev, @beta flags), which this table does not cover; the
checker shows how pre-releases such as 1.3.0-RC1 are handled.
^ by default (composer require writes it for you): it follows semantic versioning, including the 0.x rule.~ with three numbers (~1.2.3) to allow patch updates only. With two numbers it behaves like Ruby's ~> and pip's ~=: see ~> vs ~= vs ~."1.2") expecting a range: it is an exact pin on 1.2.0.≥1.2.0 and <2.0.0: the last number you wrote (2) may increase. npm and Cargo read the same ~1.2 as ≥1.2.0 <1.3.0. Write ~1.2.0 in Composer if you want patch updates only.
With three numbers: ^1.2.3 = ≥1.2.3 <2.0.0 and ~1.2.3 = ≥1.2.3 <1.3.0. With two numbers they are the same for 1.x and above: ^1.2 = ~1.2 = ≥1.2.0 <2.0.0. Below 1.0 they differ: ^0.3 = <0.4.0 but ~0.3 = <1.0.0.
No. A bare version without an operator or wildcard is an exact constraint, padded with zeros: "1.2" matches 1.2.0 only. Write "1.2.*" for the whole 1.2.x line. (In npm, a bare 1.2 means 1.2.x.)
A space or a comma means “and” (>=1.2 <2.0 or >=1.2,<2.0); || means “or” (^1.2 || ^2.0). Hyphen ranges like 1.2 - 2.3 include the whole 2.3.x line.
^ and ~ into [project] dependencies (Poetry 2, uv)