What ^0.0.3 matches in npm

>=0.0.3 <0.0.4

^0.0.3 matches >=0.0.3 <0.0.4, which in practice is version 0.0.3 and nothing else. The caret keeps the leftmost non-zero number fixed, and in 0.0.3 that’s the patch, so there’s no room left to move.

Against real versions

0.0.2          no
0.0.3          yes
0.0.3+build.7  yes   build metadata is ignored: this is 0.0.3
0.0.3-rc.1     no    a prerelease sorts below 0.0.3
0.0.4          no
0.1.0          no

The upper bound compiles to <0.0.4-0, below every prerelease of 0.0.4, so nothing between 0.0.3 and 0.0.4 can match either.

Why npm pins it

node-semver, npm’s range engine, assumes any 0.0.x release may break the one before it, since SemVer 2.0.0 promises nothing before 1.0.0. The caret allows only updates it considers non-breaking, so here it allows none. npm install still saves such a package with the default save-prefix, as ^0.0.3: it reads like a range but acts like the exact version.

The tilde is looser here

^0.0.3   >=0.0.3 <0.0.4
~0.0.3   >=0.0.3 <0.1.0
^0.0     <0.1.0

~0.0.3 keeps the major and minor and lets the patch rise, so it accepts 0.0.4, 0.0.9 and every other 0.0.x from 0.0.3 on. That’s the range to write if you trust a 0.0.x package’s patch releases. ^0.0 reaches as far, but it would also accept 0.0.1 and 0.0.2.

Gotchas

  • npm update does nothing for it. Every newer release is outside the range, so updating means a new install: npm install pkg@latest.
  • Several copies. Two packages that want ^0.0.3 and ^0.0.4 of the same dependency can’t share one version, so npm installs both.

Elsewhere

Cargo reads ^0.0.3, and the plain "0.0.3", as >=0.0.3, <0.0.4 too, and Composer’s docs give ^0.0.3 the same bounds. Both treat a 0.0.x dependency like npm does: it only moves when you move it.

Try it in the Semver Range Checker

^0.0.3 means >=0.0.3 <0.0.4 — from 0.0.3 up to, but not including, 0.0.4

2 of 6 versions match — the newest is 0.0.3.

Each version · 6 versions
VersionFits the range
0.0.2
0.0.3
0.0.3+build.7 (0.0.3)
0.0.3-rc.1
0.0.4
0.1.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.