Knowledge

npm ci vs npm install: when to use which

#Development

npm install resolves dependencies and updates your lockfile as it goes. npm ci does a clean, exact install straight from the lockfile, which is what you want in CI and production builds.

Published by Mark van Eijk on June 23, 2026 · 1 minute read

  1. What npm install does
  2. What npm ci does
  3. The catch: the lockfile must exist and match
  4. When to use which

What npm install does

npm install is the everyday command for adding and updating dependencies:

npm install
npm install lodash       # add a package

It reads package.json, resolves versions, installs them, and writes the result to package-lock.json. (npm ships with Node itself, see how to install Node.js if it's missing on a server.) If a dependency allows a newer version within its range, the lockfile can change. That flexibility is exactly what you want while developing.

What npm ci does

npm ci (clean install) is built for automated and reproducible installs:

npm ci

It behaves differently in three important ways:

  • It installs exactly what is in package-lock.json, ignoring version ranges in package.json.
  • It deletes node_modules first, so you always start from a clean slate.
  • It never writes to package.json or package-lock.json.

It is also typically faster than npm install because it skips dependency resolution.

The catch: the lockfile must exist and match

npm ci requires a package-lock.json (or npm-shrinkwrap.json), and that lockfile must be in sync with package.json. If they disagree, it fails on purpose rather than silently "fixing" things:

npm ci can only install packages when your package.json and
package-lock.json are in sync. ...

The fix is to run npm install locally, commit the updated lockfile, and try again.

When to use which

Situation Use
Day-to-day development npm install
Adding or upgrading a package npm install <pkg>
CI / CD pipelines npm ci
Production / Docker builds npm ci

The rule of thumb: if you want reproducible, lockfile-exact installs, use npm ci. If you intend to change your dependencies, use npm install. Because npm ci wipes node_modules, it also clears up the kind of half-installed state that otherwise has people deleting the folder by hand.

The same logic applies to deploy scripts: run npm ci && npm run build as part of a zero-downtime deployment, so every release builds from the exact locked versions. If a Laravel app then complains about missing assets, see Vite manifest not found.

Subscribe to our newsletter

Do you want to receive regular updates with fresh and exclusive content to learn more about web development, hosting, security and performance? Subscribe now!