Caret vs tilde in npm: ^ and ~ ranges

^ allows minor and patch updates; ~ allows only patch updates

A caret range allows minor and patch updates, a tilde range only patch updates: ^1.2.3 means >=1.2.3 <2.0.0, and ~1.2.3 means >=1.2.3 <1.3.0. Both start at the version you wrote; they differ in how far up they reach.

Side by side

The same five releases against each range:

version   ^1.2.3   ~1.2.3
1.2.3     yes      yes
1.2.9     yes      yes
1.3.0     yes      no
1.9.9     yes      no
2.0.0     no       no

The tool below starts on ~1.2.3. Pick the ^1.2.3 chip to watch 1.3.0 and 1.9.9 join.

Where they meet

The caret keeps the leftmost non-zero number fixed, so below 1.0.0 it narrows. ^0.2.3 is >=0.2.3 <0.3.0, the same as ~0.2.3. ^0.0.3 is >=0.0.3 <0.0.4, tighter than ~0.0.3, which reaches <0.1.0. With only a major written, the tilde widens instead: ~1 is >=1.0.0 <2.0.0, the same as ^1.

Which one npm writes

npm install pkg saves a caret, because the save-prefix setting defaults to ^. npm config set save-prefix='~' makes later installs write a tilde, and --save-exact (-E) writes the bare version.

The range is only consulted when versions get resolved. package-lock.json records the exact version installed; npm install keeps it as long as it still satisfies package.json, and npm ci installs exactly what the lockfile lists. npm update is what moves a dependency up within its range, so on a locked project the choice of ^ or ~ decides how far npm update may go.

npx semver -r '~1.2.3' 1.2.9 1.3.0    # prints 1.2.9

Other package managers

  • pnpm defaults its savePrefix setting to ^, and Yarn (2 and later) its defaultSemverRangePrefix; yarn add -T writes ~ and yarn add -E no prefix. Both resolve npm ranges with the same semver package.
  • Cargo reads ^ and ~ the same way, but a bare "1.2.3" in Cargo.toml means ^1.2.3. In package.json, bare 1.2.3 is that version exactly.
  • Composer agrees on ^1.2.3 and ~1.2.3, but reads ~1.2 as >=1.2 <2.0.0: the last number written may rise. npm reads ~1.2 as >=1.2.0 <1.3.0.

Try it in the Semver Range Checker

~1.2.3 means >=1.2.3 <1.3.0 — from 1.2.3 up to, but not including, 1.3.0

2 of 5 versions match — the newest is 1.2.9.

Each version · 5 versions
VersionFits the range
1.2.3
1.2.9
1.3.0
1.9.9
2.0.0

Follows node-semver, npm's range grammar: caret ^, tilde ~, x-ranges 1.2.x, hyphen ranges 1.2.3 - 2, || and comparators. A prerelease like 1.9.9-beta only matches when the range names a prerelease on the same 1.9.9 — that is why ^1.2.3 skips it. Everything runs in this page, nothing is uploaded.

Runs in your browser. Nothing you enter is sent anywhere.