Revision 1 — the current text. The evidence on this page is this revision’s own — it has not been carried forward from, or to, any other revision.
Diagnosing a missing module npm install silently didn't provide
Confirms the module truly isn't installed, then checks the two most common install-time reasons: a platform-specific optionalDependency (native addons like esbuild/sharp binaries) skipped because the install environment's OS/architecture didn't match the runtime environment's, and a lockfile out of sync with package.json. It does not cover an ESM 'ERR_MODULE_NOT_FOUND' extension or exports-map error, which is a resolution-time problem with a package that IS installed, covered by a separate playbook.
npm reporting success doesn't guarantee everything your code imports actually landed in node_modules — optional/platform-specific packages and lockfile drift are both silent by design in different ways.
What happens next
passed → step 2, Is the missing module actually present in node_modules?
Step 2 · TestIs the missing module actually present in node_modules?
Confirm the directory genuinely doesn't exist before assuming this is an install problem at all.
Read-onlysh
ls node_modules/<package-name>
Expected result
ls: cannot access 'node_modules/<package-name>': No such file or directory
What happens next
passed → step 3, Is it a platform-specific optional dependency (a native addon)?
failed → step 4, The package is actually installed — this isn't a missing-install problem
unknown → step 3, Is it a platform-specific optional dependency (a native addon)?
Step 3 · TestIs it a platform-specific optional dependency (a native addon)?
Packages like esbuild, sharp, or @swc/core ship per-platform binary packages under optionalDependencies, which npm silently skips installing when they don't match the current OS/CPU. That's by design, not a bug.
passed → step 5, Root cause: install and runtime environments don't share an OS/architecture
failed → step 6, Does package.json list the dependency, and does the lockfile agree?
unknown → step 6, Does package.json list the dependency, and does the lockfile agree?
Step 4 · EndThe package is actually installed — this isn't a missing-install problem
Check the exact import path and casing instead (Linux is case-sensitive; a path that works on macOS/Windows can 404 on Linux CI), or a package.json 'exports' restriction blocking a deep import — that's covered by the ESM ERRMODULENOT_FOUND playbook, not this one.
Step 5 · Root causeRoot cause: install and runtime environments don't share an OS/architecture
If the environment that ran npm install (for example an earlier Docker build stage, or a CI cache) has a different OS or CPU architecture than the one actually running the app, the platform package for the runtime environment never gets installed. Run npm install (or npm ci) inside the actual target environment/architecture rather than copying a node_modules built elsewhere, or explicitly install the correct platform package there.
Step 6 · TestDoes package.json list the dependency, and does the lockfile agree?
Check both files for the dependency, and confirm the lockfile actually matches the package manager being used to install (an npm ci run against a yarn.lock, or vice versa, won't add anything).
passed → step 7, Fix: resync the lockfile with package.json
failed → step 8, package.json and the lockfile already agree
unknown → step 8, package.json and the lockfile already agree
Step 7 · FixFix: resync the lockfile with package.json
The dependency is listed in package.json but missing (or mismatched) in the lockfile — commonly because a lockfile update wasn't committed, a merge conflict dropped the entry, or the wrong package manager's lockfile is in use. Regenerate it, then commit the result.
Changes statesh
Changes system or service state. Review before running.
Rewrites package-lock.json to match package.json (adding the missing entry) and installs into node_modules; commit the updated lockfile afterward so CI and other clones stay in sync.
npm install
Step 8 · Endpackage.json and the lockfile already agree
This isn't a missing-entry problem — check whether the install step actually ran in the directory containing this package.json at all (a monorepo/workspace-root vs subpackage mismatch is a common way for npm install to report success while installing a different package.json's dependencies), or whether a project .npmrc points installs at a different registry that silently no-ops for a private package it can't reach.
What would strengthen it: 6 more independent reproductions. Reproductions from 3 more distinct environments.
This counts only what was recorded against revision 1 itself. Nothing reported against another revision is included here — see the revision history for why.