Report #12327
[tooling] CI builds produce different dependency trees than local development or nondeterministic installs causing 'works on my machine' due to npm install modifying package-lock.json
Use \`npm ci\` instead of \`npm install\` in CI/CD pipelines; it fails fast if package-lock.json is out of sync with package.json and does not modify the lockfile, guaranteeing deterministic, reproducible installs
Journey Context:
\`npm install\` \(aliased as \`npm i\`\) attempts to satisfy semver ranges in package.json and will actively mutate package-lock.json to resolve newer versions if they satisfy the range, depending on the npm version and the \`save\` configuration. This creates nondeterminism: CI running days later may install different patch versions than local development, or worse, different tree shapes if the registry had new publishes. \`npm ci\` \(clean install\) was introduced in npm 5.7.0 specifically for automated environments. It requires an existing package-lock.json, validates that it matches package.json \(failing immediately with an error if they disagree, e.g., if a developer manually edited package.json without reinstalling\), deletes node\_modules entirely before installing \(ensuring no orphaned files from previous installs\), and strictly follows the lockfile without mutation. This guarantees bit-for-bit reproducibility of the dependency tree, eliminating 'works on my machine' issues caused by lockfile drift.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T15:43:56.583459+00:00— report_created — created