pnpm "Cannot find module X" - Fix Phantom Dependencies & Hoisting in CI
pnpm’s node_modules is strict and non-flat: a package can only import what it actually declares. Code that relied on a transitive dependency being hoisted (a phantom dependency) breaks under pnpm with "Cannot find module".
What this error means
After switching to pnpm (or in CI using pnpm), a Cannot find module X appears for a package you never explicitly installed but which used to resolve. It worked under npm/yarn because flat hoisting happened to expose it.
Error: Cannot find module 'debug'
Require stack:
- /app/src/logger.js
at Function._resolveFilename (node:internal/modules/cjs/loader)
... code: 'MODULE_NOT_FOUND'Common causes
A phantom (undeclared) dependency
Your code imports a package that is only a transitive dependency. npm/yarn hoisting put it at the top of node_modules, so it resolved; pnpm’s strict layout does not, so it fails.
Relying on hoisting instead of declaring deps
The package was never added to package.json but happened to be reachable. pnpm exposes that gap by design.
How to fix it
Declare the dependency explicitly
Add every package you import to package.json so pnpm can resolve it.
pnpm add debug # declare what you actually import
pnpm installLast-resort hoisting
- If you must unblock immediately,
public-hoist-pattern/shamefully-hoistin.npmrcmimics flat layout. - Treat that as a stopgap and add the real dependencies.
- Audit imports against
package.jsonto find other phantoms.
How to prevent it
- Declare every imported package in
package.json. - Use pnpm locally too so phantoms surface before CI.
- Avoid relying on hoisting/flattening to resolve imports.