TLDR: npm install can update your npm packages potentially destabilizing your build process by using untested dependency versions. Use npm ci instead!
If you’re like me you might have several node-based apps, nicely configured to be built and deployed using automatic build & release pipelines.
So one of the first things you’re probably doing in that build pipeline is installing all required dependencies from npm, with your process looking something like this:
So what’s the issue with npm install?
Take a look at your package.json file. In there, you’ll find all of your apps dependencies, including their version numbers. Chances are that a lot of them are prefixed with either ~ or ^ meaning that npm install will not necessarily download the exact version specified but will potentially download newer packages if available.
This can lead to situations where builds start failing because of a botched update to a dependency. Or even worse, the build could still pass and take down your app. And all without you even changing a line of code.
enter npm ci
When you install the dependencies using npm ci, it will delete your node_modules folder before anything else to ensure a clean environment (which should not be necessary in your pipeline – you didn’t check in this folder, did you?).
Next thing it does is install your npm packages, but instead of looking at the packages.json file for your dependencies & version numbers, it will get this information from the package-lock.json file. So make sure you checked that one in as well.
The package-lock.json contains the exact dependency configuration that you last ran on your local machine. That way you can be sure that the Build Server will also build exactly the same app that you have tested. You’ll often see that changes were made to that file after an npm install – that’s a good indicator that a newer package version of one of the dependencies was added.
What do I need to do?
Just replace your npm install command with npm ci – it’s really that simple!