node.js - What's the difference between tilde(~) and caret(^) in package.json?

ID : 84

viewed : 138

Tags : node.jsnpmpackage.jsonsemantic-versioningnode.js

Top 5 Answer for node.js - What's the difference between tilde(~) and caret(^) in package.json?

vote vote


See the NPM docs and semver docs:

  • ~version “Approximately equivalent to version”, will update you to all future patch versions, without incrementing the minor version. ~1.2.3 will use releases from 1.2.3 to <1.3.0.

  • ^version “Compatible with version”, will update you to all future minor/patch versions, without incrementing the major version. ^2.3.4 will use releases from 2.3.4 to <3.0.0.

See Comments below for exceptions, in particular for pre-one versions, such as ^0.2.3

vote vote


I would like to add the official npmjs documentation as well which describes all methods for version specificity including the ones referred to in the question

value desc
~version "Approximately equivalent to version"
See npm semver - Tilde Ranges
^version "Compatible with version"
See npm semver - Caret Ranges
version Must match version exactly
>version Must be greater than version
>=version etc
1.2.x 1.2.0, 1.2.1, etc., but not 1.3.0
* Matches any version
latest Obtains latest release

The above list is not exhaustive. Other version specifiers include GitHub urls and GitHub user repo's, local paths and packages with specific npm tags

Official Docs

vote vote


npm allows installing newer version of a package than the one specified. Using tilde (~) gives you bug fix releases and caret (^) gives you backwards-compatible new functionality as well.

The problem is old versions usually don't receive bug fixes that much, so npm uses caret (^) as the default for --save.

semver table

According to: "Semver explained - why there's a caret (^) in my package.json?".

Note that the rules apply to versions above 1.0.0 and not every project follows semantic versioning. For versions 0.x.x the caret allows only patch updates, i.e., it behaves the same as the tilde. See "Caret Ranges"

Here's a visual explanation of the concepts:

semver diagram

Source: "Semantic Versioning Cheatsheet".

vote vote



<major>.<minor>.<patch>-beta.<beta> == 1.2.3-beta.2 
  • Use npm semver calculator for testing. Although the explanations for ^ (include everything greater than a particular version in the same major range) and ~ (include everything greater than a particular version in the same minor range) aren't a 100% correct, the calculator seems to work fine.
  • Alternatively, use SemVer Check instead, which doesn't require you to pick a package and also offers explanations.

Allow or disallow changes

  • Pin version: 1.2.3.
  • Use ^ (like head). Allows updates at the second non-zero level from the left: ^0.2.3 means 0.2.3 <= v < 0.3.
  • Use ~ (like tail). Generally freeze right-most level or set zero if omitted:
  • ~1 means 1.0.0 <= v < 2.0.0
  • ~1.2 means 1.2.0 <= v < 1.3.0.
  • ~1.2.4 means 1.2.4 <= v < 1.3.0.
  • Ommit right-most level: 0.2 means 0.2 <= v < 1. Differs from ~ because:
    • Starting omitted level version is always 0
    • You can set starting major version without specifying sublevels.

All (hopefully) possibilities

Set starting major-level and allow updates upward

*  or "(empty string)   any version 1                         v >= 1 

Freeze major-level

~0 (0)            0.0 <= v < 1 0.2               0.2 <= v < 1          // Can't do that with ^ or ~  ~1 (1, ^1)        1 <= v < 2 ^1.2              1.2 <= v < 2 ^1.2.3            1.2.3 <= v < 2 ^1.2.3-beta.4     1.2.3-beta.4 <= v < 2 

Freeze minor-level

^0.0 (0.0)        0 <= v < 0.1 ~0.2              0.2 <= v < 0.3 ~1.2              1.2 <= v < 1.3 ~0.2.3 (^0.2.3)   0.2.3 <= v < 0.3 ~1.2.3            1.2.3 <= v < 1.3 

Freeze patch-level

~1.2.3-beta.4     1.2.3-beta.4 <= v < 1.2.4 (only beta or pr allowed) ^0.0.3-beta       0.0.3-beta.0 <= v < 0.0.4 or 0.0.3-pr.0 <= v < 0.0.4 (only beta or pr allowed) ^0.0.3-beta.4     0.0.3-beta.4 <= v < 0.0.4 or 0.0.3-pr.4 <= v < 0.0.4 (only beta or pr allowed) 

Disallow updates

1.2.3             1.2.3 ^0.0.3 (0.0.3)    0.0.3 

Notice: Missing major, minor, patch or specifying beta without number, is the same as any for the missing level.

Notice: When you install a package which has 0 as major level, the update will only install new beta/pr level version! That's because npm sets ^ as default in package.json and when installed version is like 0.1.3, it freezes all major/minor/patch levels.

vote vote


As long as the first number ("major") is at least 1:

~ locks major and minor numbers. It is used when you're ready to accept only bug-fixes (increments in the third number), but don't want any other changes, not even minor upgrades that add features.

^ locks the major number only. It is used when you are willing to receive bug fixes (increments in the third number) and minor upgrades that add features but should not break existing code (increments in the second number). However you do not want changes that break existing code (increments in the first number).

In addition to that, ^ is not supported by old npm versions, and should be used with caution.

So, ^ is a good default, but it's not perfect. I suggest to carefully pick and configure the semver operator that is most useful to you.

(Revised to avoid saying "fixes" and "bug-fixes" with conflicting use of "fixes", which is confusing)

Top 3 video Explaining node.js - What's the difference between tilde(~) and caret(^) in package.json?