The reason to use npm’s shrinkwrap feature is that, while you can fix the versions of your direct dependencies in your package.json, you can’t fix the versions of their dependencies, which may be quite loosely specified. This means that if you or someone else rebuilds the image at some future time, you can’t guarantee (without using shrinkwrap) that it won’t pull down a different version of some indirect dependency, breaking your app. This seems to happen to me much more often than one might expect, so I advocate using shrinkwrap. If you are familiar with ruby’s excellent bundler dependency manager, npm-shrinkwrap.json is much like Gemfile.lock.
Source: Lessons from Building a Node App in Docker
Dependencies in the node ecosystem can be a real pain in the ass. Some relief can be had by using npm shrinkwrap to manage the dependencies of your dependencies.