How to Fix Error: Cannot Find Module in Node.js
Diagnose and fix Node.js Error: Cannot find module 'X' — from missing installs and case sensitivity to ESM/CJS mismatches and TypeScript aliases.
How to Fix "Error: Cannot find module" in Node.js
The full stack trace usually looks like this:
Error: Cannot find module 'lodash'\nRequire stack:\n- /app/src/index.js\n at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1077:15)\n at Function.Module._load (node:internal/modules/cjs/loader:922:27)Node's module resolver walked node_modules up the directory tree and never found the package. Work through these six causes in order — the first one that matches is almost always the fix.
1. Is the package actually installed?
Check whether the module exists in node_modules at all:
npm ls lodash\n# or\nls node_modules/lodashIf npm ls prints (empty) or the directory is missing, install it. Also verify the dependency is declared in package.json — running your app on a fresh clone won't install packages that were only added ad-hoc on another machine:
npm install lodash --save\n# for dev-only tools\nnpm install --save-dev typescriptIf it is a dev dependency, remember that NODE_ENV=production npm install skips devDependencies entirely.
2. Is the name spelled correctly (and cased correctly)?
Linux and Docker containers use case-sensitive filesystems; macOS and Windows are case-insensitive by default. Code that runs fine locally can break in CI with:
Error: Cannot find module 'React'The published package is react, lowercase. Fix the import:
// wrong\nconst React = require('React');\n// right\nconst React = require('react');Watch for similar traps: Express vs express, and scoped packages like @types/Node vs @types/node.
3. Corrupted or partial node_modules
A killed install, a Node version switch, or mixing npm and yarn can leave the tree half-built. Nuke and reinstall:
# npm\nrm -rf node_modules package-lock.json\nnpm install\n\n# pnpm\nrm -rf node_modules pnpm-lock.yaml\npnpm install\n\n# Windows PowerShell\nRemove-Item -Recurse -Force node_modules, package-lock.json\nnpm installAlso clear the npm cache if the install itself is throwing integrity errors: npm cache clean --force.
4. ESM vs CommonJS mismatch
Node picks a module system per file. A common error is:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/app/src/utils' imported from /app/src/index.jsUnder ESM, imports must include the file extension. Fix by adding .js:
// wrong (ESM)\nimport { hello } from './utils';\n// right\nimport { hello } from './utils.js';Other ESM pitfalls:
- Set
\"type\": \"module\"inpackage.jsonto make.jsfiles ESM, or rename entry files to.mjs. - If you publish a library, use the
\"exports\"field inpackage.json— a missing subpath inexportsthrowsERR_PACKAGE_PATH_NOT_EXPORTED, which frequently surfaces as "Cannot find module 'pkg/internal'". - You cannot
require()a package that only ships ESM (e.g.node-fetchv3+). Switch toimport()or downgrade.
5. TypeScript path aliases not resolved at runtime
You compile TypeScript with paths in tsconfig.json:
{\n \"compilerOptions\": {\n \"baseUrl\": \".\",\n \"paths\": { \"@app/*\": [\"src/*\"] }\n }\n}...and then Node crashes with:
Error: Cannot find module '@app/users/service'The TypeScript compiler understands @app/*, but Node has no idea what that means. Options:
- Rewrite paths at build time with
tsc-alias:tsc && tsc-alias. - Resolve at runtime:
node -r tsconfig-paths/register dist/index.js, or forts-nodeset\"ts-node\": { \"require\": [\"tsconfig-paths/register\"] }. - If you use a bundler (Vite, esbuild, Next.js), set
\"moduleResolution\": \"bundler\"— but do not usebundlerfor code that Node runs directly. Use\"nodenext\"or\"node16\"for pure Node (note: nodenext/node16 require explicit `.js` extensions on relative imports and honor the `exports` field strictly — use "node" for legacy CJS projects) projects.
6. Monorepo hoisting and pnpm strict mode
In a Yarn/npm workspace, packages get hoisted to the root node_modules, so a workspace can accidentally import a transitive dependency it never declared. Under pnpm (strict by default), the same code fails:
Error: Cannot find module 'chalk'\n Note: chalk is a dependency of 'commander', not the current package.Fix it the right way — add the dependency to that workspace's own package.json:
pnpm --filter @acme/api add chalkIf you truly need hoisting (some legacy tools require it), add to .npmrc:
public-hoist-pattern[]=*chalk*\n# or, less safe\nshamefully-hoist=trueStill stuck?
Print the resolver's search path with NODE_DEBUG=module node or inspect require.resolve.paths('X') in a REPL. Nine times out of ten the module is not where you think it is — the trace shows exactly which directories Node checked, and the fix follows immediately.