CodePark/ questions / Node apps in Docker
START PRACTICINGPRACTICE
Backend question · Docker › Node apps in Docker

Why use npm ci rather than npm install in a Dockerfile, and what does --omit=dev add?

Use npm ci because it installs exactly what the lock file says, so every build is the same. --omit=dev makes the image smaller by skipping dev-only packages.

What npm ci does:

  • It is made for automated, clean installs.
  • It needs a package-lock.json file.
  • It installs exactly the versions in that lock file.
  • It fails if the lock file and package.json disagree. It does not quietly update them.
  • It deletes any existing node_modules folder first.

This makes builds reproducible: the image gets the same dependency tree that you tested.

Why not npm install: it can pick newer versions inside your version ranges. It can also rewrite the lock file. So two builds of the same commit could end up different.

What --omit=dev adds: it skips devDependencies, such as test frameworks, linters and TypeScript. This makes the runtime image smaller. It also removes code that has no reason to be in production.

One caveat: in a TypeScript build stage, you still need the dev dependencies to compile the code.

  • npm ci installs exactly the versions in the lock file.
  • npm ci fails if the lock file and package.json do not match.
  • This makes builds reproducible: the same commit gives the same image.
  • --omit=dev skips devDependencies.
  • A build stage still needs dev dependencies to compile the code.