Hello readers, Today we are going to discuss about very common yet important package manager command npm install. I am sure you are using it, whether you are a front-end engineer or a backend (api / devops) engineer.

npm install or nowadays npx i or npm i is so common to use, but I doubt whether you have also used npm ci yet ?

So lets keep the ball rolling and continue to our discussion...

Lets first understand how exactly npm install works:

To make use of tools (or packages) in Node.js, we need to be able to install and manage them in a useful way. This is where npm, the Node package manager, comes in picture. It installs the packages you want to use and provides a useful interface to work with them. Not to mention we define /save our packages in so called package.json file. This is the place where npm reads your dependency and/or dev dependency and continues to installs them within your project.

During this process npm also creates a lock file, known as package-lock.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates.

This file is intended to be committed into source repositories, and serves various purposes:

  • Describe a single representation of a dependency tree such that teammates, deployments, and continuous integration are guaranteed to install exactly the same dependencies.
  • Provide a facility for users to “time-travel” to previous states of node_modules without having to commit the directory itself.
  • To facilitate greater visibility of tree changes through readable source control diffs.
  • And optimize the installation process by allowing npmto skip repeated metadata resolutions for previously-installed packages.

That said, there are a few catches, like if you are using:

  • ^ or ~ when you specify the version of your dependency, npm install may not install the exact version you specified.
  • npm install can update your package-lock.json when there are changes such as when you install a new dependency.

This is fine when as long as we are developing or working on project, but may turn into unwanted failures during testing / automated deployments.

The questions here is, so how do we overcome this problem? Well this is where npm ci comes to your rescue. Lets understand how it helps.

npm-ci: Installing packages with a clean state

This command is similar to npm-install, except it’s meant to be used in automated environments such as test platforms, continuous integration, and deployment – or any situation where you want to make sure you’re doing a clean install of your dependencies. It can be significantly faster than a regular
npm install by skipping certain user-oriented features. It is also more strict than a regular install, which can help catch errors or inconsistencies caused by the incrementally-installed local environments of most npm users.

DO & DON'Ts:

npm ci will ALWAYS do the following things:

  • Delete your node_modules before continuing.
  • Look at your package.json to install all the dependencies with the exact same version.
  • Will throw an error and exit when your dependency do not match between package.json and package-lock.json

npm ci will NEVER do the following things:

  • It will never modify your package-lock.json.
  • It will never write to package.json.

Requirements to use npm ci

  • We must have a package-lock.json file in your project — if you don't, npm ci will not work and you will have to use npm install to generate one.


As you can see, both commands have their valid use cases.

  • We must use npm install to install new dependencies, or to update existing dependencies.
  • We must use npm ci when running in continuous integration, or if you want to install dependencies without modifying the package-lock.json.

Thank you for reading this article. I am sure it must have helped you gain some knowledge to you.