What this usually means
Your local machine has a warm `node_modules` directory with cached builds. Native modules (like `bcrypt`, `sharp`, `node-sass`) were compiled for your OS and architecture long ago. CI starts from a clean slate — no cache, no build tools, possibly a different OS or CPU architecture. The install fails because the environment lacks the toolchain needed to compile native addons. Alternatively, your `package-lock.json` is out of sync with `package.json` because you added a dependency without running `npm install` to regenerate the lockfile. Locally, npm might silently fix this, but `npm ci` in CI strictly enforces lockfile consistency.
The first ten minutes \u2014 establish facts before touching code.
- 1Check the CI log for the first error. Is it `node-gyp`? `python not found`? `make: command not found`?
- 2Compare `npm install` vs `npm ci` behaviour. Most CI pipelines use `npm ci` which requires a clean, up-to-date lockfile.
- 3Check if `package-lock.json` is committed and matches `package.json`. Run `npm install` locally and see if the lockfile changes.
- 4Check if the CI runner OS matches your local OS. Native modules compiled for macOS will not work on a Linux CI runner.
- 5Check if optional dependencies are causing failures. Some packages have optional native deps that fail on unsupported platforms.
The specific files, logs, configs, and dashboards that usually own this bug.
- searchCI pipeline config — install command, Node version, OS image
- searchCI job log — first error from the install step
- search`package.json` vs `package-lock.json` — are they in sync?
- searchDependencies with native modules — `bcrypt`, `sharp`, `node-sass`, `canvas`, `puppeteer`
- searchCI runner image documentation — pre-installed build tools
- search`.npmrc` or `.yarnrc` — registry config, platform-specific settings
Practical causes, not theory. These are the things you will actually find.
- warningNative module needs `node-gyp` but CI runner lacks Python, make, or a C++ compiler
- warning`package-lock.json` is out of date — `npm ci` rejects it but `npm install` locally auto-fixes
- warningCI runner is a different OS or CPU architecture (e.g. macOS vs Linux, x64 vs arm64)
- warningA package requires a specific Node version and CI runs a different one
- warningOptional dependency fails to install and the error is not handled
- warningA dependency is listed in `devDependencies` but CI runs with `--production` flag
- warningPrivate package registry is not accessible from CI (missing `.npmrc` with auth token)
Concrete fix directions. Pick the one that matches your root cause.
- buildRun `npm ci` locally instead of `npm install` — this simulates the CI environment on a clean slate
- buildAdd required build tools to the CI config: `sudo apt-get install build-essential python3` for Linux runners
- buildCommit `package-lock.json` and keep it in sync — run `npm install` after every dependency change
- buildUse `--ignore-scripts` temporarily to identify if the failure is in a postinstall script
- buildPin the CI runner OS to match the target deployment environment (usually Linux)
- buildAdd a `.npmrc` with the auth token for private registries as a CI secret
A fix you cannot prove is a guess. Close the loop.
- verifiedPush a commit. CI install step should pass.
- verifiedDelete `node_modules` locally and run `npm ci`. It should succeed.
- verifiedRun `npm ci` in a Docker container matching the CI image. It should succeed.
- verifiedCheck that `package-lock.json` has no uncommitted changes after `npm install`.
- verifiedVerify native modules build correctly on the CI runner OS.
Things that make this bug worse or harder to find.
- warningRunning `npm install` instead of `npm ci` in CI — `npm ci` is faster and stricter
- warningNot committing `package-lock.json` to the repository
- warningAdding build tools globally on the CI runner instead of declaring them in the CI config
- warningUsing `--force` or `--legacy-peer-deps` to paper over dependency conflicts
- warningAssuming `node_modules` from a previous CI run is clean enough to reuse