Package Versions in composer.json
You have probably seen various "^3.2", "~3.2" in the composer.json file. Let's figure out what these symbols mean and which package versions they support.
Let's start with a general example that shows all possible options. Example of the composer.json file:
{
"require": {
"author/package": ">=5.6",
"author/package": "~2.0.14",
"author/package": "~2.0.0",
"author/package": "~2.0.0 || ~2.1.0",
"author/package": "dev-master",
"author/package": "*",
"author/package": "2.4.1"
},
"require-dev": {
"author/package": "~2.1.0",
"author/package": "~2.1.0",
"author/package": "~2.0.0",
"author/package": "^4.0",
"author/package": "^1.0",
"author/package": "^1.0",
"author/package": "^1.0",
"author/package": "~0.5.0 || ~1.1.0",
"author/package": ">=2.7 <=4.2.4"
}
}
Exact Version
Allows only the specified package version. Explicitly specified without any symbols:
"erusev/parsedown": "1.7"
Version Ranges
Allows updating the package within the specified version range.
dev-masterfor example "dev-master"- Allows all versions, including the latest commits to the master branch.
>for example ">1.7"- Allows anything greater than the specified version.
>=for example ">=1.7"- Allows anything greater than or equal to the specified version.
<for example "<1.7"- Allows anything less than the specified version.
<=for example "<=1.7"- Allows anything less than or equal to the specified version.
!=for example "!=1.7"- Allows everything except the specified version.
*for example "1.1.*"Wildcard. Represents any number. It is used to specify a version template.
1.0.*includes all versions1.0,1.0.1,1.0.2,1.0.3, and so on.
~for example "~1.2.3"Tilde operator. Allows the last specified digit to be incremented.
Usually used to denote the minimum minor version on which the code depends.
-
~1.2is the same as>=1.2 <2.0.0(allows all until 2.0, but not including 2.0). ~1.2.3is the same as>=1.2.3 <1.3.0(allows all until 1.3, but not including 1.3).
Example:
// The package version is greater than or equal to 2.0.14 but less than 2.1 "erusev/parsedown": "~2.0.14"
-
^for example "^1.2.3"Caret operator. Similar to tilde, but allows incrementing all numbers except the first (major version).
Usually used to denote the minimum major version. It specifies the main acceptable version and allows all nested (minor) versions.
-
^1.2.3is the same as>=1.2.3 <2.0.0(allows all until 2.0, but not including 2.0). - If the major version starts with
0, it allows all updates up to the second number. For versions before1.0, it also considers update safety and treats^0.3as>=0.3.0 <0.4.0.
This is the recommended operator for compatibility when writing/using a library.
Example:
"erusev/parsedown": "^4.0"
-
Combining Ranges
Multiple ranges can be specified simultaneously:
for example ">2.7 <4.2.4",for example ">2.7,<4.8"- Logical AND. A space or comma between versions means AND.
||for example "2.0.0 || 2.1.0"|for example "^1|^2"Logical OR. Double vertical bar means OR.
NOTE: In older versions of Composer, the single pipe
|was the recommended alternative to logical OR. Therefore, for backward compatibility,|is still considered as logical OR.
AND takes precedence over OR.
Examples:
// Greater than or equal to version 2.6 "erusev/parsedown": ">=2.6" // Greater than version 2.7 AND less than version 4.2.4 "erusev/parsedown": ">2.7 <4.2.4" // Version 2.0.0 OR version 2.1.0 "erusev/parsedown": "2.0.0 || 2.1.0"
Version Range with Dash -
The dash - indicates which set of versions is suitable: from version - to version. The rightmost unspecified number in the version is supplemented with *.
For example, 1.0 - 2.0 is the same as >=1.0.0 <2.1, as 2.0 becomes 2.0.*.
However, if you specify the third (last) number of the version, then there is no place for the * and the right version is considered the last valid one: 1.0.0 - 2.1.0 is the same as >=1.0.0 <=2.1.0.
Example:
// Greater than or equal to 2.0 but less than 3.1 "erusev/parsedown": "2.0 - 3.0"
Stability Constraints
Add the suffix -stable if you need to load only stable versions.
If no suffix is specified, Composer under the hood will use -dev or -stable, depending on the specified operator:
| Specified Version | How Composer interprets it |
|---|---|
| 1.2.3 | =1.2.3.0-stable |
| >1.2 | >1.2.0.0-stable |
| >=1.2 | >=1.2.0.0-dev |
| >=1.2-stable | >=1.2.0.0-stable |
| <1.3 | <1.3.0.0-dev |
| <=1.3 | <=1.3.0.0-stable |
| 1 - 2 | >=1.0.0.0-dev <3.0.0.0-dev |
| ~1.3 | >=1.3.0.0-dev <2.0.0.0-dev |
| 1.4.* | >=1.4.0.0-dev <1.5.0.0-dev |
Aliases
When for a Composer package version we specify a branch (for example, dev-main), and not a version, we may encounter a conflict if a dependency requires, for example, version 1.0.*. An alias solves this problem:
- you tell Composer to treat
dev-mainas1.0.x-dev.
Then dev-main looks like version 1.0.*, and the dependency does not conflict.
Note: dev- prefix in Composer:
Composer always marks branches as dev-{branch_name}. That is:
- Branch
mainin Composer will bedev-main bugfix=dev-bugfix.feature/foo=dev-feature/foo.
Why:
Composer distinguishes "versions" (tags: 1.2.3, 1.0.x) and "branches" (dev-main, dev-dev).
To avoid confusion, branches receive the dev- prefix.
This is the standard and part of the version comparison rules in Composer.
Inline alias (alias in require)
Composer allows specifying aliases directly in require when you need to temporarily use your branch with a bugfix in a dependency.
For example:
- you found a bug in
monolog/monolog - forked it
- created a
bugfixbranch - want to use that code in your project
But your project uses symfony/monolog-bundle, which requires monolog/monolog version 1.*.
You need to make your dev-bugfix branch satisfy that constraint.
In the root composer.json file:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/you/monolog"
}
],
"require": {
"symfony/monolog-bundle": "2.0",
"monolog/monolog": "dev-bugfix as 1.0.x-dev"
}
}
Important notes:
-
Inline alias works only in the root project - only in the composer.json of your project (the one where you run "composer install"). Inside dependencies (in their own composer.json) aliases do not work and are ignored.
- Inline alias should be avoided, especially in public packages. If there is a bug - send a PR to the original repository.
Branch alias (branch alias)
A branch alias allows giving a branch like dev-main a semantic version, for example 1.0.x-dev.
{
"extra": {
"branch-alias": {
"dev-main": "1.0.x-dev"
}
}
}
Constraints:
-
You can alias only versions that are comparable. For example:
- Allowed:
"dev-main": "1.0.x-dev" - Not allowed:
"dev-main": "dev-master"
- Allowed:
-
You can alias comparable versions, but only to more specific ones. For example:
- Allowed:
1.x-dev: 1.2.x-dev,2.x-dev: 2.1.x-dev - Not allowed:
1.2.x-dev: 1.x-dev,2.3.x-dev: 2.0.x-dev
- Allowed:
-
The alias for a branch must be stored in that same branch.
- To use a branch alias, you must own the package repository. If you want to alias someone else's package without creating a fork, use an inline alias.
Total
"require": {
// only version 1.3.2
"author/package": "1.3.2",
// >, <, >=, <= | specify upper / lower bounds
"author/package": ">=1.3.2", // anything greater than or equal to 1.3.2
"author/package": "<1.3.2", // less than 1.3.2
// * | wildcard
"author/package": "1.3.*", // >=1.3.0 <1.4.0
// ~ | allows incrementing the last specified digit
"author/package": "~1.3.2", // >=1.3.2 <1.4.0
"author/package": "~1.3", // >=1.3.0 <2.0.0
// ^ | does not allow critical changes
"author/package": "^1.3.2", // >=1.3.2 <2.0.0
"author/package": "^0.3.2", // >=0.3.2 <0.4.0
// OR
"phpunit/phpunit": "^3||^4||^5||^6||^7||^8||^9",
// old variant
"phpunit/phpunit": "^3|^4|^5|^6|^7|^8|^9",
}
--
Official documentation: https://getcomposer.org/doc/articles/versions.md