5155

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?
BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Fizer Khan
  • 88,237
  • 28
  • 143
  • 153
  • 67
    FYI you can prevent prefixes or use a custom one by doing: `npm config set save-prefix=''`. (Stick `~` in the quotes if that's what you prefer.) I personally do this and shrinkwrap for things in production. – fncomp Jan 22 '15 at 09:48
  • 27
    All the nitty gritty details of how tilde and caret work and differences: https://github.com/npm/node-semver#tilde-ranges-123-12-1 – Jeffrey Martinez Oct 13 '15 at 21:31
  • 13
    This tool is a great helper to test https://semver.npmjs.com/ – chaiyachaiya Dec 13 '16 at 12:57
  • 1
    [Semantic versioning](https://docs.npmjs.com/about-semantic-versioning) in npm and node – RBT Jan 10 '19 at 08:33
  • 1
    Docs for [`npm shrinkwrap`](https://docs.npmjs.com/cli/v6/commands/npm-shrinkwrap) and [package-lock.json vs npm-shrinkwrap.json](https://docs.npmjs.com/cli/v7/configuring-npm/package-lock-json#package-lockjson-vs-npm-shrinkwrapjson) #toSaveYouAGoogle (or two) -- fncomp mentions [above](https://stackoverflow.com/questions/22343224#comment44548771_22343224) and tehfoo [below](https://stackoverflow.com/questions/22343224#comment45166739_22345808). Also, mneumonic: `~` stays about even, `^` goes up a little higher. – ruffin May 28 '21 at 19:56
  • I created this video to help in understanding it: https://youtu.be/3XKIs1_FpLw – Benny Code Mar 24 '23 at 14:37

20 Answers20

5919

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. ^1.2.3 will use releases from 1.2.3 to <2.0.0.

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

mikemaccana
  • 110,530
  • 99
  • 389
  • 494
jgillich
  • 71,459
  • 6
  • 57
  • 85
  • 615
    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. – tehfoo Feb 09 '15 at 18:33
  • 54
    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=''` – kumarharsh Jul 08 '15 at 06:11
  • 15
    @prasanthv is right: from https://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. – rofrol Oct 11 '15 at 16:19
  • 36
    @jgillich in semver when you use `0.2.x`, `2` isn't a `major version`. That's why https://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 – rofrol Oct 12 '15 at 10:14
  • Hat matching is broken because it wont update `^0.1.2` to `0.2.0`. The rule is: always version your package skipping the `0.x.x` version range and you'll get consistent behaviour – catamphetamine Oct 19 '15 at 11:29
  • 18
    @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. – Maciej Sz Oct 22 '15 at 14:22
  • 1
    @MaciejSz I'm sorry but I didn't understand. Are you saying that the behavior for `0.0.x` is different than the behavior of `~0.0.0` or that the behavior of `0.x.0` is different than the behavior of `^0.0.0`? Or are you arguing that the `0.x.0`/`^0.0.0` pattern is better than `0.0.x`/`~0.0.0` in the context you provided? – Fagner Brack Oct 22 '15 at 19:30
  • 7
    @FagnerBrack: I'm saying that when using tilde you can define minimum version number (at the least significant version number). With the `0.0.x` notation you don't have that option because **any** least significant version number will be valid. – Maciej Sz Oct 26 '15 at 12:22
  • 1
    @MaciejSz Now I understand, specifying a minimum version instead of the latest "x" is indeed a valid use case. Very good point. Although I would recommend using neither the "x" or "~" notation to ensure consistency between multiple developers. – Fagner Brack Oct 26 '15 at 16:26
  • You now have * wich updates to most recent update regardless the version. – Matias Jul 21 '16 at 19:30
  • 1
    It's worth noting that you can use [npm semver](https://semver.npmjs.com/) to calculate version ranges for a specific package. – Wildhoney Mar 06 '17 at 08:21
  • 3
    Caret ups to latest Minor, not Major. It's `Major`, `Minor`, `Patch`, `Hotfix`. – adi518 Feb 28 '18 at 16:47
  • In the `pre-5.x` npm the symbols (`~`/`^`) were affecting the downloaded dependencies during `npm install`. After `5.x` the existence of `package-lock.json` next to `package.json` prevents this. For updating project dependencies based on the rules described in this post, `npm update` can be used (which updates also `package-lock.json`), followed by commit of both `package.json` and `package-lock.json`. – Marinos An May 14 '18 at 10:58
  • 1
    This is wrong. As pointed out ^ specifies to update to minor versions & patches (middle & last number), & ~ specifies to only update to patch releases (last number). "Major" is the first number in semantic versioning, specifying breaking changes, which you don't want to auto-update to. Never saw such a glaringly wrong answer with upvoted so highly on here. It's a bit concerning. – Peter Out Jun 12 '18 at 19:19
  • 3
    I have edited this answer to correct the explanation. Instead of complaining about a wrong answer in its comments, please DO SOMETHING about it next time! – Ian Kemp Aug 31 '18 at 09:58
  • The caret will NOT update to the most recent major version. Only minor and patch versions. – Remi Sture Sep 15 '18 at 06:48
  • This answer is unsalvageable because it is formed around quoting nonsense. The answer from pspi is correct and should be voted up. The terminology is not somehow misleading. It is nonsense. If you call a dog a horse, and then you say that horses eat meat and bark you're not talking something somehow misleading. – 9ilsdx 9rvj 0lo Sep 25 '18 at 10:02
  • 1
    We have an issue here folks... WHY does this have 2764 up-votes if it's misleading or incorrect? Maybe don't hit the up-vote button unless you're 100% sure about what you're voting on seems like good practice. Ian, take it down a notch... if an answer is wrong, misleading or confusing... then it deserves discussion, instead of stepping all over each others toes with the edit link. – Chad Oct 24 '18 at 18:23
  • 1
    The links in this accepted answer are broken. The best current official documentation link is https://github.com/npm/node-semver#versions – clay Jun 14 '21 at 15:03
  • If any NPM devs are reading this . . . in my ideal world, none of this fuzzy versioning would be allowed, because of malware risks. Any fuzzy versioning in your package.json leaves you continually trusting that the developers of your packages do not publish malware and are not hacked or otherwise tricked into doing so. See here for an example: https://github.com/advisories/GHSA-pjwm-rvh2-c87w – William Jockusch Oct 26 '21 at 16:45
  • AND THEN... there's also a lot of extra rules if you use `-` or `+` in the version numbers as well! `-` means "prerelease" and has additional rules that aren't obvious, and `+` means build and has different rules? so much fun to diagnose these! – John Gardner Jan 20 '23 at 18:58
1617

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, i.e., only accept new patch versions
See npm semver - Tilde Ranges
^version Compatible with version, i.e., accept new minor and patch versions
See npm semver - Caret Ranges
version Must match version exactly
>version Must be greater than version
>=version etc
<version
<=version
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

ryenus
  • 15,711
  • 5
  • 56
  • 63
Ahmad
  • 22,657
  • 9
  • 52
  • 84
  • 46
    It is also possible to specify an exact range of versions, like `1.2.0 || >=1.2.2 <1.3.0`: Exactly 1.2.0, or everything from 1.2.2 to 1.3.0 (inclusive), but not 1.2.1, or 1.3.1 and above, and also not 1.1.x and below. – CodeManX Jun 08 '16 at 20:30
  • 1
    A more specific link form the above -> https://docs.npmjs.com/files/package.json#dependencies – Toby Jul 11 '18 at 12:38
  • 22
    `"Approximately equivalent to version"` and `"Compatible with version"` are such frustratingly non-specific ways to describe ~ and ^ behavior. Thank you @jgillich for providing an actual answer! – Scott Stafford Jul 17 '19 at 15:21
  • Another resource : https://nodejs.dev/learn/semantic-versioning-using-npm – potame Jun 30 '21 at 08:45
  • Is `latest` recommend for debs that never depend on versions? Does the question makes sense at all.. – Timo Aug 01 '21 at 16:04
  • 1
    @Timo "deps that never depend on versions" probably don't exist. You can have deps that don't **currently** depend on versions, but future versions of the dependency are not guaranteed to be backwards compatible so unless you own the dependency as well as the application it's a safe bet that eventually 'latest' won't work. To me it seems the best use for a 'latest' specifier is during early development, proof-of-concepts, or for short term projects that will not be maintained long term. – Segfault Nov 17 '21 at 14:11
  • So is `~1.2.0` 100% equivalent to `1.2.x`? Because `1.2.x` is a lot easier to understand! – Simon_Weaver Jun 14 '22 at 19:05
  • 2
    @Simon_Weaver In that case, with a patch version of `0`, yes they are equivalent. But if you had, for example, `~1.2.3`, that's equivalent to `>=1.2.3 <1.3.0`, whereas `1.2.x` would be equivalent to `>=1.2.0 <1.3.0` --- essentially the `~` means _any patch version greater than or equal to the one specified_, whereas the `x` in that position means _any number_. Full syntax is defined here: https://github.com/npm/node-semver#advanced-range-syntax – Toastrackenigma Jul 06 '23 at 02:02
891

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".

Ronan Boiteau
  • 9,608
  • 6
  • 34
  • 56
pspi
  • 11,189
  • 1
  • 20
  • 18
  • 3
    What about ^0.2.5? from https://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. – rofrol Oct 11 '15 at 16:18
  • 21
    @rofrol any version before 1.0.0 is considered unstable and these rules don't apply – pspi Nov 04 '15 at 09:35
  • 3
    So your explanation isn't complete – rofrol Nov 04 '15 at 10:22
  • 8
    @rofrol yeah, omitting for readability is good sometimes, chances of having anything below 1.0.0 for a dependency in package json are pretty low. see also 20/80 principle, is a great rule for focusing on what matters – pspi Nov 04 '15 at 16:42
  • 12
    @pspi Having versions below 1.0.0 is "unlikely"? Out of 60 we've got ~15, and most of them aren't obscure. – Dave Newton Aug 08 '16 at 21:08
  • @DaveNewton ouch... even if the version is above 1.0.0 there are no guarantees that the project is following semver, though – pspi Aug 09 '16 at 12:18
  • 1
    I like this answer, except the `3.*.*` in the table seems confusing. It implies that 3.8.8 could satisfy the `^3.9.2`. It would not – bigh_29 Apr 24 '21 at 21:14
150

Semver

<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.

rofrol
  • 14,438
  • 7
  • 79
  • 77
  • Telling people to avoid starting projects from 0 because library and consuming developers don't understand the system is a terrible solution. I think @asdfasdfads has much better information. – ProLoser Sep 22 '16 at 19:16
  • @ProLoser I just think that the system should be simplified, and we shouldn't use 0.x versions. – rofrol Sep 23 '16 at 08:16
  • 2
    The use case around early lifecycle development and v0 makes a LOT of sense. Learning how v0 behaves properly has actually made me look forward to other early-lifecycle projects. It means you can have a rapidly changing API with lots of backwards incompatibility without being forced to declare your project as 1.x (aka: stable) when it really isn't. – ProLoser Sep 23 '16 at 17:26
  • I understand it, but I just don't like how it works with semver and qualifiers – rofrol Sep 23 '16 at 20:03
  • 5
    It feels more like an opinion and shouldn't be framed as a generally accepted approach. And ^0.1.x gets patches perfectly fine. – ProLoser Oct 11 '16 at 16:01
  • @ProLoser But you won't get `^0.1.x` by default when installing from npm. Most likely it will be `^0.1.3` which dissalows any updates. Anyway I have dropped the advice for not using `0.*` and just added notice. – rofrol Apr 30 '17 at 09:46
125

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)

ProfDFrancis
  • 8,816
  • 1
  • 17
  • 26
alex
  • 11,935
  • 3
  • 30
  • 42
  • 14
    not true: 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. https://docs.npmjs.com/misc/semver#caret-ranges-1-2-3-0-2-5-0-0-4 – rofrol Oct 11 '15 at 16:08
  • 6
    This answer is completely wrong (as are many other here). None of these ever fix a major number! As @rofrol said, ^ simply keeps the left most non-zero digit unchanged. ~ on the other hand allows only patch updates if the minor version is specified (e.g. ~1.2.3 or ~1.2) and allows minor updates if the minor version is not specified (e.g. ~1). – TheBaj Jul 14 '17 at 14:22
  • 3
    @TheBaj They mean "fix" as "define" ("fixate") rather than "adjust", so you all agree on how the major number gets handled. – maaartinus Jul 10 '18 at 21:41
  • 1
    Yes, this answer seemed totally backwards until I realized the answerer meant "fix" as in "to make fixed, stationary, or unchanging." – nCardot Nov 05 '19 at 05:57
68

~ : Reasonably close to

   ~1.1.5: 1.1.0 <= accepted < 1.2.0

^: Compatible with

   ^1.1.5: 1.1.5 <= accepted < 2.0.0

   ^0.1.3: 0.1.3 <= accepted < 0.2.0

   ^0.0.4: 0.0.4 <= accepted < 0.1.0
chharvey
  • 8,580
  • 9
  • 56
  • 95
haotang
  • 5,520
  • 35
  • 46
  • 20
    @kytwb - no. In the special case of zeroth-release version numbers, the carat is equivalent to the tilde. Thus `^0.1.3` only accepts versions `0.1.x` and will not accept `0.2.0`, even though that's a minor increment. This behavior is equivalent to `~0.1.3`. The reasoning behind this behavior is due to the fact that zeroth-release packages are still considered unstable; in the words of [semver.org](http://semver.org/), #4, "anything may change at any time" (including backwards-incompatible changes). – chharvey Feb 25 '15 at 20:45
  • Wouldn't that last example not allow patch upgrades either? – Feathercrown Jul 31 '23 at 20:55
46

~ Tilde:

  • ~ freezes major and minor numbers.
  • It is used when you're ready to accept bug-fixes in your dependency, but don't want any potentially incompatible changes.
  • The tilde matches the most recent minor version (the middle number).
  • ~1.2.3 will match all 1.2.x versions, but it will miss 1.3.0.
  • Tilde (~) gives you bug fix releases

^ Caret:

  • ^ freezes the major number only.
  • It is used when you're closely watching your dependencies and are ready to quickly change your code if minor release will be incompatible.
  • It will update you to the most recent major version (the first number).
  • ^1.2.3 will match any 1.x.x release including 1.3.0, but it will hold off on 2.0.0.
  • Caret (^) gives you backwards-compatible new functionality as well.
coding_idiot
  • 13,526
  • 10
  • 65
  • 116
Laxmi
  • 3,830
  • 26
  • 30
  • 2
    The tilde matches the most recent patch version (the last number). The caret matches the most most recent minor version (the middle number). – Abdul Rauf Mar 30 '18 at 04:25
  • 1
    "freezes" is the best explanation. – mhrabiee Sep 04 '19 at 09:36
  • Caret both freezes the major number and will update you to the most recent major version (the first number)? The major number is the first number, so this doesn't make sense. – nCardot Jan 29 '20 at 23:57
45

^ is 1.[any].[any] (latest minor version)
~ is 1.2.[any] (latest patch)

A great read is this blog post on how semver applies to npm
and what they're doing to make it match the semver standard
http://blog.npmjs.org/post/98131109725/npm-2-0-0

Will Stern
  • 17,181
  • 5
  • 36
  • 22
  • 2
    not true: 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. https://docs.npmjs.com/misc/semver#caret-ranges-1-2-3-0-2-5-0-0-4 – rofrol Oct 11 '15 at 16:07
37

Hat matching may be considered "broken" because it wont update ^0.1.2 to 0.2.0. When the software is emerging use 0.x.y versions and hat matching will only match the last varying digit (y). This is done on purpose. The reason is that while the software is evolving the API changes rapidly: one day you have these methods and the other day you have those methods and the old ones are gone. If you don't want to break the code for people who already are using your library you go and increment the major version: e.g. 1.0.0 -> 2.0.0 -> 3.0.0. So, by the time your software is finally 100% done and full-featured it will be like version 11.0.0 and that doesn't look very meaningful, and actually looks confusing. If you were, on the other hand, using 0.1.x -> 0.2.x -> 0.3.x versions then by the time the software is finally 100% done and full-featured it is released as version 1.0.0 and it means "This release is a long-term service one, you can proceed and use this version of the library in your production code, and the author won't change everything tomorrow, or next month, and he won't abandon the package".

The rule is: use 0.x.y versioning when your software hasn't yet matured and release it with incrementing the middle digit when your public API changes (therefore people having ^0.1.0 won't get 0.2.0 update and it won't break their code). Then, when the software matures, release it under 1.0.0 and increment the leftmost digit each time your public API changes (therefore people having ^1.0.0 won't get 2.0.0 update and it won't break their code).

Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes,
MINOR version when you add functionality in a backwards-compatible manner, and
PATCH version when you make backwards-compatible bug fixes.
catamphetamine
  • 4,489
  • 30
  • 25
  • This comment was ridiculously helpful and doesn't seem to be documented very well. Do you have a link to the documentation around this behavior? This answer about v0 projects has helped me a lot. – ProLoser Sep 22 '16 at 19:15
  • I don't have a link: I found this information too by googling and playing with npm semantic version calculator https://semver.npmjs.com/ – catamphetamine Sep 23 '16 at 12:01
  • 2
    Needs to be added to their documentation in a more formal way. I gave a talk at Sony to my engineering team because it seems to so easily get overlooked. http://slides.com/proloser/semver-v0 – ProLoser Sep 23 '16 at 17:27
33

caret ^ include everything greater than a particular version in the same major range.

tilde ~ include everything greater than a particular version in the same minor range.

For example, to specify acceptable version ranges up to 1.0.4, use the following syntax:

  • Patch releases: 1.0 or 1.0.x or ~1.0.4
  • Minor releases: 1 or 1.x or ^1.0.4
  • Major releases: * or x

For more information on semantic versioning syntax, see the npm semver calculator.

npm semantic versions in published packages§

More from npm documentation About semantic versioning

t0r0X
  • 4,212
  • 1
  • 38
  • 34
ElasticCode
  • 7,311
  • 2
  • 34
  • 45
31

Tilde (~)

major version is fixed, the minor version is fixed, matches any build number

"express": "~4.13.3" 

~4.13.3 means it will check for 4.13.x where x is anything

Caret (^)

major version is fixed, matches any minor version, matches any build number

"supertest": "^3.0.0"

^3.0.0 means it will check for 3.x.x where x is anything

Farhan Yaseen
  • 2,507
  • 2
  • 22
  • 37
  • 2
    Can you elaborate on how this answer is different from [the same answer posted 4 years ago](https://stackoverflow.com/questions/22343224/whats-the-difference-between-tilde-and-caret-in-package-json/22365742#22365742)? – Franklin Yu Nov 06 '18 at 19:31
26

One liner explanation

The standard versioning system is major.minor.build (e.g. 2.4.1)

npm checks and fixes the version of a particular package based on these characters

~ : major version is fixed, minor version is fixed, matches any build number

e.g. : ~2.4.1 means it will check for 2.4.x where x is anything

^ : major version is fixed, matches any minor version, matches any build number

e.g. : ^2.4.1 means it will check for 2.x.x where x is anything

Avinash
  • 4,115
  • 2
  • 22
  • 41
24

Tilde ~ matches minor version, if you have installed a package that has 1.4.2 and after your installation, versions 1.4.3 and 1.4.4 are also available if in your package.json it is used as ~1.4.2 then npm install in your project after upgrade will install 1.4.4 in your project. But there is 1.5.0 available for that package then it will not be installed by ~. It is called minor version.

Caret ^ matches major version, if 1.4.2 package is installed in your project and after your installation 1.5.0 is released then ^ will install major version. It will not allow to install 2.1.0 if you have ^1.4.2.

Fixed version if you don't want to change version of package on each installation then used fixed version with out any special character e.g "1.4.2"

Latest Version * If you want to install latest version then only use * in front of package name.

remix23
  • 2,632
  • 2
  • 11
  • 21
Mudassir
  • 578
  • 4
  • 6
  • 3
    This answer is misleading. SemVer clearly states, *A normal version number MUST take the form X.Y.Z [where] X is the major version, Y is the minor version, and Z is the patch version.* – Leo Feb 28 '19 at 15:03
17

You probably have seen the tilde (~) and caret (^) in the package.json. What is the difference between them?

When you do npm install moment --save, It saves the entry in the package.json with the caret (^) prefix.

The tilde (~)

In the simplest terms, the tilde (~) matches the most recent minor version (the middle number). ~1.2.3 will match all 1.2.x versions but will miss 1.3.0.

The caret (^)

The caret (^), on the other hand, is more relaxed. It will update you to the most recent major version (the first number). ^1.2.3 will match any 1.x.x release including 1.3.0, but will hold off on 2.0.0.

Reference: https://medium.com/@Hardy2151/caret-and-tilde-in-package-json-57f1cbbe347b

Community
  • 1
  • 1
Abdou Sameh
  • 189
  • 3
  • 7
  • Again, this answer is misleading. SemVer clearly states, *A normal version number MUST take the form X.Y.Z [where] X is the major version, Y is the minor version, and Z is the patch version.* – Leo Feb 28 '19 at 15:06
7

semver is separate in to 3 major sections which is broken by dots.

major.minor.patch
1.0.0

These different major, minor and patch are using to identify different releases. tide (~) and caret (^) are using to identify which minor and patch version to be used in package versioning.

~1.0.1
 Install 1.0.1 or **latest patch versions** such as 1.0.2 ,1.0.5
^1.0.1
 Install 1.0.1 or **latest patch and minor versions** such as 1.0.2 ,1.1.0 ,1.1.1
ireshika piyumalie
  • 2,226
  • 22
  • 22
6

Related to this question you can review Composer documentation on versions, but here in short:

  • Tilde Version Range (~) - ~1.2.3 is equivalent to >=1.2.3 <1.3.0
  • Caret Version Range (^) - ~1.2.3 is equivalent to >=1.2.3 <2.0.0

So, with Tilde you will get automatic updates of patches but minor and major versions will not be updated. However, if you use Caret you will get patches and minor versions, but you will not get major (breaking changes) versions.

Tilde Version is considered "safer" approach, but if you are using reliable dependencies (well-maintained libraries) you should not have any problems with Caret Version (because minor changes should not be breaking changes.

You should probably review this stackoverflow post about differences between composer install and composer update.

milan.latinovic
  • 2,217
  • 1
  • 21
  • 26
5

Not an answer, per se, but an observation that seems to have been overlooked.

The description for caret ranges:

see: https://github.com/npm/node-semver#caret-ranges-123-025-004

Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple.

Means that ^10.2.3 matches 10.2.3 <= v < 20.0.0

I don't think that's what they meant. Pulling in versions 11.x.x through 19.x.x will break your code.

I think they meant left most non-zero number field. There is nothing in SemVer that requires number-fields to be single-digit.

t0r0X
  • 4,212
  • 1
  • 38
  • 34
Jesse Chisholm
  • 3,857
  • 1
  • 35
  • 29
  • 1
    Just a note, the wording was fixed in the meantime: `Allows changes that do not modify the left-most non-zero element`. – t0r0X Dec 04 '21 at 00:02
5

For example for : ~1.8.0 you will match all of them 1.8.x versions, but you will lose 1.9.0 (This has been the default behavior).

For example for : ^1.8.0 you will be updated to the latest major version (the first issue). Any 1.x.x release including 1.9.0, but keeping the distance from version 2.0.0

Example 3.9.2:

Symbol     Dependency   Versions    Changes
tilde (~)   ~3.9.2        3.9.*      -bug fix

caret (^)   ^3.9.2        3.*.*      -backwards compatible new functionality 
                                     -old functionality deprecated, but operational
                                     -large internal refactor
                                     -bug fix
Leandro Ariel
  • 727
  • 8
  • 5
4

The version number is in syntax which designates each section with different meaning. syntax 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.

  • 1
    Can you elaborate on how this answer is different from [the same answer posted 4 years ago](https://stackoverflow.com/questions/22343224/whats-the-difference-between-tilde-and-caret-in-package-json/22365742#22365742)? – Franklin Yu Nov 06 '18 at 19:33
3

Tilde ~ specifies to minor version releases

Caret ^ specifies to major version releases

For example, if package version is 4.5.2, on update:

~4.5.2 will install latest 4.5.x version (MINOR VERSION)

^4.5.2 will install latest 4.x.x version (MAJOR VERSION)

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
neeraj-dixit27
  • 2,812
  • 2
  • 15
  • 6
  • 11
    Can you elaborate on how this answer is different from [the same answer posted 4 years ago](https://stackoverflow.com/questions/22343224/whats-the-difference-between-tilde-and-caret-in-package-json/22365742#22365742)? – Franklin Yu Nov 06 '18 at 19:32