What's the difference between a tilde (~) and a caret (^) in a npm package.json file?
If you use npm to manage packages in your JavaScript application, you’re probably familiar with the package.json file.
{ "dependencies": { "@angular/common": "8.2.4", "@angular/compiler": "8.2.4", "@angular/core": "8.2.4", } }
The syntax is in JSON format where the key is the name of the package and the value is the version of the package to be used.
npm uses the package.json file to specify the version of a package that your app depends on.
The version number is in semver syntax which designates each section with different meaning. semver is broken into three sections separated by a dot.
major.minor.patch 1.0.2
Major, minor and patch represent the different releases of a package.
npm uses the tilde (~) and caret (^) to designate which patch and minor versions to use respectively.
So if you see ~1.0.2 it means to install version 1.0.2 or the latest patch version such as 1.0.4. If you see ^1.0.2 it means to install version 1.0.2 or the latest minor or patch version such as 1.1.0.
But if in your npm package.json file you’re referencing a package that hasn’t reached version 1.0 yet, using the caret symbol will only grab the patch version.
Tilde Ranges ~1.2.3 ~1.2 ~1
Allows patch-level changes if a minor version is specified on the
comparator. Allows minor-level changes if not.
~1.2.3
:=>=1.2.3 <1.(2+1).0
:=>=1.2.3 <1.3.0
~1.2
:=>=1.2.0 <1.(2+1).0
:=>=1.2.0 <1.3.0
(Same as1.2.x
)~1
:=>=1.0.0 <(1+1).0.0
:=>=1.0.0 <2.0.0
(Same as1.x
)~0.2.3
:=>=0.2.3 <0.(2+1).0
:=>=0.2.3 <0.3.0
~0.2
:=>=0.2.0 <0.(2+1).0
:=>=0.2.0 <0.3.0
(Same as0.2.x
)~0
:=>=0.0.0 <(0+1).0.0
:=>=0.0.0 <1.0.0
(Same as0.x
)~1.2.3-beta.2
:=>=1.2.3-beta.2 <1.3.0
Note that prereleases inthe
1.2.3
version will be allowed, if they are greater than orequal to
beta.2
. So,1.2.3-beta.4
would be allowed, but1.2.4-beta.2
would not, because it is a prerelease of adifferent
[major, minor, patch]
tuple.
Caret Ranges ^1.2.3 ^0.2.5 ^0.0.4
Allows changes that do not modify the left-most non-zero digit in the
[major, minor, patch]
tuple. In other words, this allows patch and
minor updates for versions 1.0.0
and above, patch updates for
versions 0.X >=0.1.0
, and no updates for versions 0.0.X
.
Many authors treat a 0.x
version as if the x
were the major
"breaking-change" indicator.
Caret ranges are ideal when an author may make breaking changes
between 0.2.4
and 0.3.0
releases, which is a common practice.
However, it presumes that there will not be breaking changes between
0.2.4
and 0.2.5
. It allows for changes that are presumed to be
additive (but non-breaking), according to commonly observed practices.
^1.2.3
:=>=1.2.3 <2.0.0
^0.2.3
:=>=0.2.3 <0.3.0
^0.0.3
:=>=0.0.3 <0.0.4
^1.2.3-beta.2
:=>=1.2.3-beta.2 <2.0.0
Note that prereleases inthe
1.2.3
version will be allowed, if they are greater than orequal to
beta.2
. So,1.2.3-beta.4
would be allowed, but1.2.4-beta.2
would not, because it is a prerelease of adifferent
[major, minor, patch]
tuple.^0.0.3-beta
:=>=0.0.3-beta <0.0.4
Note that prereleases in the0.0.3
version only will be allowed, if they are greater than orequal to
beta
. So,0.0.3-pr.2
would be allowed.
When parsing caret ranges, a missing patch
value desugars to the
number 0
, but will allow flexibility within that value, even if the
major and minor versions are both 0
.
^1.2.x
:=>=1.2.0 <2.0.0
^0.0.x
:=>=0.0.0 <0.1.0
^0.0
:=>=0.0.0 <0.1.0
A missing minor
and patch
values will desugar to zero, but also
allow flexibility within those values, even if the major version is
zero.
^1.x
:=>=1.0.0 <2.0.0
^0.x
:=>=0.0.0 <1.0.0