DEV Community

Cover image for 0.2.3 doesn't mean what you think: npm's caret below 1.0
Versyka
Versyka

Posted on AI-assisted

0.2.3 doesn't mean what you think: npm's caret below 1.0

The caret in package.json is so common that most people read it the same way every time: "accept new minors and patches, not majors".

That's right for versions 1.0 and up. Below 1.0, it isn't.

The rule

npm's caret allows changes that don't modify the leftmost non-zero number:

^1.4.2  →  >=1.4.2  <2.0.0     (minors and patches)
^0.2.3  →  >=0.2.3  <0.3.0     (patches only)
^0.0.3  →  >=0.0.3  <0.0.4     (that exact version)
Enter fullscreen mode Exit fullscreen mode

You can check any range yourself:

npx semver -r "^0.2.3" 0.2.9 0.3.0
# 0.2.9
Enter fullscreen mode Exit fullscreen mode

Why it works this way

Semantic versioning says that before 1.0, anything may change at any time. npm's compromise is to treat the first non-zero number as the "major". So 0.2 → 0.3 is a breaking release as far as your range is concerned, and it should be.

What it means day to day

0.x packages stay put. npm update won't move ^0.2.3 to 0.3.0, so a pre-1.0 dependency can fall far behind without anything in your workflow noticing.

The bump that "looks minor" isn't. When you finally go from 0.2.x to 0.3.0, read the changelog like it's a major. It often is.

The tilde is stricter still. ~1.4.2 allows only patches (<1.5.0). For 0.x, ^ and ~ end up close to the same thing.

A quick audit

List your direct dependencies that are still pre-1.0:

node -e 'const p=require("./package.json");for(const [k,v] of Object.entries({...p.dependencies,...p.devDependencies}))if(/^[\^~]?0\./.test(v))console.log(k,v)'
Enter fullscreen mode Exit fullscreen mode

Then compare each against its latest release. Versyka's free upgrade check does that comparison for a whole package.json in one paste, no sign-up.

How many of your dependencies start with ^0?

Top comments (0)