Conquering npm shrinkwrap (in layman's terms)
July 20, 2016
We’ve all been there. You start with a simple app idea and get to work. With the vast number of packages available on npmjs.org, your dependency list begins to grow exponentially. You then hear about a neat npm CLI command called  shrinkwrap .
What is it?
[Shrinkwrap] locks down the versions of a package’s dependencies so that you can control exactly which versions of each dependency will be used when your package is installed.
– npmjs
Life without shrinkwrap
Because  package.json  often specifies only a minimum version number, another person using your package could run  npm install  and end up with different dependency versions than you.
For example, let’s say Developer-A runs  npm i --save-dev surprise-pkg@1.0.0  and pushes his changes to Github.  Package.json  now reads  "surprise-pkg: "^1.0.0" . Developer-B comes along some time later, clones the same repo, and runs  npm install . To his surprise, he notices that  surprise-pkg  installs version  1.9.9 , even though his package.json reads the same as Developer-A’s.
Do you see why that could be a problem? Developer-A and Developer-B are now developing with different versions of  surprise-pkg !
Shrinkwrap to the rescue
The scenario above can be easily resolved with  npm shrinkwrap . Not without a few headaches, of course. But that’s why this was written… so you could wrap your head around the mystery of shrinkwrapping!
So, let’s backtrack. Developer-A runs  npm i --save-dev surprise-pkg@1.0.0  again, but this time he runs  npm shrinkwrap --dev  before committing and pushing his changes to Github.  Package.json  still reads  "surprise-pkg: "^1.0.0" , but there is a new file-  npm-shrinkwrap.json . If Developer-A were to dig into this file, among all of the other dependencies he would find the following:
“surprise-pkg”: { “version”: “1.0.0”, “resolved”: ”https://registry.npmjs.org/surprise-pkg/-/surprise-pkg-1.0.0.tgz” }
Now, when Developer-B comes along, clones the same repo, and runs  npm install , he would find  surprise-pkg@1.0.0  was installed too. Now both developers can code in harmony with the same version of  surprise-pkg !
Order of operations (Installing)
It is important to understand the precedence of  package.json  and  npm-shrinkwrap.json . Here are a few pointers:
When you run  npm install …
1. If  npm-shrinkwrap.json  exists, ONLY the dependencies specified in your shrinkwrap file will be installed.
2. Otherwise, dependencies in  package.json  will be installed according to the semantic version specified (like the above example).
You can also ignore an existing shrinkwrap with the  --ignore-shrinkwrap  flag.
CAUTION: I don’t advise you ignore shrinkwrap unless you know what you are doing.
Shrinkwrap best practices
When you are working on any repository that uses a shrinkwrap, you should follow these best practices to avoid causing you and your team shrinkwrap headaches.
- 
Given there is an existing shrinkwrap file, you should always npm installbefore installing any new packages or updates and subsequently runningnpm shrinkwrap.Why? Since a generated shrinkwrap is based upon what is in your node_modulesfolder, you should always make sure that your installednode_modulesmatch those that may have been recently updated & shrinkwrapped by others on your team.
- 
Don’t forget about package.json. Whenever you install a new module, remember to--saveor--save-dev.Why? It is possible to install a new module without saving it to package.jsonand still have the new version get shrinkwrapped. But then you end up with discrepancies betweenpackage.jsonandnpm-shrinkwrap.json– a developer headache.

Written by Tom Beute– a Christian who writes software and brews coffee; an artisan of both code and espresso.