Recently I noticed that project build times were getting longer and longer in work, taking up to 15 minutes to build and unit test an intranet solution. This quickly becomes unfeasible when you have a number of projects, with multiple branches and a non-infinite number of available build agents.

Examining the build logs quickly revealed the bottleneck...

npm install

Running npm install was taking over 7 minutes to complete!

Some searching revealed the existence of the npm ci command, documented here.

Designed specifically for test, continuous integration and continuous deployment environments it will mostly ignore package.json, only checking that it matches what is in package-lock.json (or package-shrinkwrap.json).

If there is a mismatch it will fail with an error instead of trying to create a new lock file. If everything matches up then it will restore from the lock file instead without having to do any dependency resolution.

It will delete any existing node_modules folder to ensure a consistent restoration of all dependencies and is guaranteed to never write to package.json or any lock files.

So what effect does this have on our build times?

npm ci

npm package restoration dropped from 7 minutes and 29 seconds to just 28 seconds! A 94% reduction in time and restoring some sanity and calm to a frustrated IT department.