Programming
node.js npm package.json semantic-versioning
Updated Sun, 07 Aug 2022 13:26:35 GMT

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


After I upgraded to the latest stable node and npm, I tried npm install moment --save. It saves the entry in the package.json with the caret ^ prefix. Previously, it was a tilde ~ prefix.

  1. Why are these changes made in npm?
  2. What is the difference between tilde ~ and caret ^?
  3. What are the advantages over others?



Solution

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





Comments (5)

  • +0 – Posting here to hopefully catch people that don't quite think this through, but both ^ and ~ assumes you can trust minor and point releases from your dependencies. If you are publishing a library and want other people to trust you, DO NOT BLINDLY ACCEPT DOWNSTREAM DEPENDENCIES. A bad dot release from your dependency can cause a chain reaction upstream, and will have people knocking at YOUR door when things go pear shaped. This is another huge reason to use npm shrinkwrap on your production code. — Feb 09, 2015 at 18:33  
  • +0 – You can also just do away with all the nonsense of npm prepending your versions with a ^ or a ~. Set this if you want to have tight control over your versions: npm config set save-prefix='' — Jul 08, 2015 at 06:11  
  • +0 – @prasanthv is right: from docs.npmjs.com/misc/semver#caret-ranges-1-2-3-0-2-5-0-0-4: 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. — Oct 11, 2015 at 16:19  
  • +0 – @jgillich in semver when you use 0.2.x, 2 isn't a major version. That's why docs.npmjs.com used the specific words: the left-most non-zero digit. Also what about this case: ^0.0.4 means 0.0.4 — Oct 12, 2015 at 10:14  
  • +0 – @FagnerBrack: The specific example you provided is correct, but generally your way of thinking is wrong. An example: let's say you have package A in 3 versions: 0.0.1, 0.0.2 and 0.0.3. There is a bug in 0.0.1 so you want to have at least 0.0.2 in your package B. If you write 0.0.x you'll get 0.0.3, which is OK. But if some other package C requires both B and A and additionally has constrain "A": "<0.0.2" you'll get 0.0.1 without showing any conflict issue, which is not what you want. Using tilde ~0.0.2 should help you avoid this issue. — Oct 22, 2015 at 14:22