"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 → checktsconfig.jsonpaths.- 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
"Command Not Found": The PATH Variable Explained
"command not found" or "is not recognized as an internal or external command" usually means the program is installed but your terminal doesn't know where to look. How PATH works on Mac, Linux and Windows, how to check it, and how to add a folder permanently.
Git Push Rejected: "Updates Were Rejected Because the Remote Contains Work"
git push fails with "rejected — fetch first" or "non-fast-forward" when GitHub has commits you don't. How to pull and combine them safely, when force-pushing is fine and when it destroys work, and the other rejection messages: protected branches, large files, and secrets.