How To Guide

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.

{ "slug": "how-to-fix-cannot-find-module-node", "title": "How to Fix Error: Cannot Find Module in Node.js", "description": "Diagnose and fix Node.js Error: Cannot find module 'X' — from missing installs and case sensitivity to ESM/CJS mismatches and TypeScript aliases.", "type": "how-to", "toolSlugs": ["bash", "read", "edit"], "keywords": ["cannot find module", "node.js error", "npm install", "esm cjs", "typescript paths", "node_modules", "module resolution"], "content": "

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/lodash

If 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 typescript

If 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 install

Also 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.js

Under 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\" in package.json to make .js files ESM, or rename entry files to .mjs.
  • If you publish a library, use the \"exports\" field in package.json — a missing subpath in exports throws ERR_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-fetch v3+). Switch to import() 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 for ts-node set \"ts-node\": { \"require\": [\"tsconfig-paths/register\"] }.
  • If you use a bundler (Vite, esbuild, Next.js), set \"moduleResolution\": \"bundler\" — but do not use bundler for 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 chalk

If you truly need hoisting (some legacy tools require it), add to .npmrc:

public-hoist-pattern[]=*chalk*\n# or, less safe\nshamefully-hoist=true

Still 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.

" }
cannot find module node.js error npm install esm cjs mismatch typescript paths node_modules module resolution pnpm hoisting

Explore 300+ Free Tools

Utilko has tools for developers, writers, designers, students, and everyday users — all free, all browser-based.