Blog
3 min read

"Cannot Find Module" and "Module Not Found": How to Fix Them

Node's "Error: Cannot find module" and bundlers' "Module not found: Can't resolve" mean an import points at something that isn't there. The five causes — not installed, wrong path, wrong case, missing build, wrong working directory — and how to fix each.

Two of the most common JavaScript errors say the same thing in different words:

Error: Cannot find module 'express'
Module not found: Can't resolve './components/Header'

Both mean: an import or require points at something that isn't where the code says it is. The first comes from Node.js; the second from a bundler like Vite, Webpack or Next.js. The fix depends on what it can't find.

Is it a package or a file?

Look at the name in quotes:

  • No ./ or ../ — like 'express' or '@supabase/supabase-js' — it's a package from npm.
  • Starts with ./ or ../ — like './utils/date' — it's a file in your project.
  • Starts with @/ or ~/ — a path alias your project defines.

Missing packages

Cause 1: It isn't installed. Most common after cloning a project or pulling changes.

npm install

If the package isn't in package.json at all, add it:

npm install express

Check the name carefully, especially if an AI suggested it — AI tools sometimes invent packages that don't exist, and some fake names are registered by attackers. (AI hallucinated packages)

Cause 2: It's installed in the wrong place. You ran npm install in a different folder from the one with package.json, or you have a monorepo and installed at the wrong level. Run npm ls express in the folder where the error happens.

Cause 3: A broken node_modules. When nothing else works:

rm -rf node_modules package-lock.json
npm install

(Deleting the lock file updates versions; try without that first.) (node_modules explained)

Cause 4: It's a dev dependency and production skipped it. If production runs npm install --omit=dev but your code imports something listed under devDependencies, it'll be missing. Move it to dependencies.

Missing files

Cause 5: Wrong relative path. ./ means "this file's folder." ../ means "one folder up." If you moved a file, its imports — and everything importing it — may now be wrong. Your editor's "go to definition" will tell you whether the path resolves. (File paths explained)

Cause 6: Wrong letter case. This is the classic "works on my Mac, fails on the server" bug. macOS and Windows treat Header.tsx and header.tsx as the same file; Linux doesn't. Make the import match the file name exactly. If you renamed a file only by case, git may not have noticed:

git mv header.tsx Header.tsx

Cause 7: A missing extension or index. In Node's native ES modules you must write the extension: import './utils.js', not './utils'. Bundlers are more forgiving. (ESM vs CommonJS)

Cause 8: Path alias not configured. @/components/Header only works if tsconfig.json (and sometimes your bundler config) defines @:

{ "compilerOptions": { "paths": { "@/*": ["./src/*"] } } }

"Cannot find module '/app/dist/index.js'"

When the missing module is your own start file, the build didn't run, put its output somewhere else, or you started from the wrong folder. Check that npm run build ran before npm start, and that the path in package.json's start script matches the build output.

The summary

  • Package names → run npm install, check the name is real, check you're in the right folder.
  • Relative paths → check the folder levels and exact letter case.
  • @/ paths → check tsconfig.json paths.
  • Your own entry file → make sure the build ran and the path matches.

EasySpawn runs your app on Linux in development and production alike, so case-sensitivity and missing-dependency bugs show up while Claude Code is working, not after you deploy. See how it works or join the waitlist.

Related: What Are npm and package.json? · File Paths Explained · npm ERESOLVE Error · Why Does My App Work Locally but Not in Production?

Keep reading