The Daily TIL

March 26, 2019 by AndyAndynpmpackagessemver

NPM Semver Calculator helps you find the right package version

I did something dumb with my NPM dependencies. After a spree of updating dependency versions in my project, surprise! I noticed that something had been broken.

(First of all, don’t do this. If it ain’t broke, don’t fix it cause often, fixing it will break it then you’ll have to fix it.)

I checked the diff on package.json, and saw that the update causing the change in behavior was a minor-version change.

-   "netlify-cms": "^2.4.2",
+   "netlify-cms": "^2.8.0",

(Ignore for now the fact that this minor version change introduced a breaking change in behavior… :sad_keanu: )

I reverted this change back to ^2.4.2 and re-deployed. I tested the new deployment, and… still broken.

Luckily, the component in question was nice enough to already log it’s current version to the browser console, and I noticed it was still logging netlify-cms 2.8.0. That was when I face-palmed and looked closer at my dependency version and saw the culprit: ^.

According to the NPM caret range docs, caret ranges allow…

…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

or ^1.2.3 := >=1.2.3 <2.0.0

I had learned that breaking changes only really happened in major version updates. So the surprising part here was that NPM assumes, an author may make breaking changes between 0.2.4 and 0.3.0 releases, which is a common practice..

Given the fact that NPM expects breaking changes to happen in minor version updates, it seems bad that ^ is the default notation that package managers use. Both npm install -s and yarn add add new packages with ^ versions.

So anyway, now I just needed to figure out how to lock down to N.N.x, or patch versions only.


Knowing I would probably forget this again 5 minutes from now, I looked for a tool to help me out, and found this:

Broken version notation ^2.4.2

You can see here that ^2.4.2 allows every release version less that 3.0.0.

ScreenCapture at Tue Mar 26 11:14:42 PDT 2019

Correct version notation ~2.5.0

After some git blaming I discovered that anything in the 2.5.x range would work for me. This tool helped me determine that ~ was the right notation to use to keep my dependency in this range.

ScreenCapture at Tue Mar 26 11:18:50 PDT 2019