Module not found: Can't resolve (webpack / Next.js / Vite)
The bundler or Node cannot find a file or package you imported. The message looks scary, but it almost always means a bad path, a missing install, a case mismatch, or an alias that only TypeScript understands.
What the error is saying
Webpack, Next.js, Vite, Metro and Node each resolve import x from "…" / require("…") against disk and node_modules. When resolution fails you see variants like:
Module not found: Error: Can't resolve './Button' in '/app/src'
Module not found: Can't resolve 'lodash/debounce'
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'xyz'
Failed to resolve import "@/lib/utils" from "pages/index.tsx"
This is not the same as a runtime crash inside a module that did load. Fix resolution first.
Cause table
| Message / clue | Likely cause | Fix |
|---|---|---|
Can't resolve './Foo' | Wrong relative path or missing extension | Check folder; on ESM you may need .js; try ../ levels carefully |
| Works on macOS, fails on Linux CI | Case mismatch (Button vs button) | Rename to exact case; enable case-sensitive checks locally |
Can't resolve 'some-pkg' | Not installed / wrong workspace | npm i some-pkg (or pnpm/yarn); check it is in this package’s package.json |
Can't resolve '@/…' | Path alias only in TypeScript | Mirror alias in next.config / Vite resolve.alias / webpack |
Package has exports map | Importing a blocked subpath | Use the documented export; avoid deep pkg/dist/… imports |
| Monorepo package name | Workspace not linked | Check workspaces, run install from root, verify package name field |
ERR_MODULE_NOT_FOUND for relative file | Node ESM needs full extension | Import ./file.js even if source is .ts (emit path) |
| CSS / image / font import | Loader / asset config missing | Confirm bundler handles that extension; check public/ vs import |
Checklist (fast)
- Read the path after
Can't resolveand thein '…'directory — resolve it by hand from that folder. - Confirm the file exists with the exact casing Linux will see.
- For bare specifiers (
react,lodash): is it listed and isnode_modulespresent? Delete lock + reinstall only as a last resort after checking the right package folder in a monorepo. - For
@/or~/aliases: grep bothtsconfig.jsonpathsand the bundler config. - If you just renamed a file, restart the dev server — some caches keep old graphs.
// tsconfig paths must be mirrored for the bundler
// tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": { "@/*": ["src/*"] }
}
}
// vite.config.ts
resolve: { alias: { "@": path.resolve(__dirname, "src") } }
// next.js usually reads tsconfig paths automatically — still verify baseUrl
ESM vs CommonJS gotchas
- Node native ESM: relative imports often need the
.jsextension. "type": "module"inpackage.jsonchanges how.jsfiles load — see also Cannot use import statement outside a module.- Some dual packages break when you import a subpath that isn’t in
exports.
Related: npm ENOENT, npm ERESOLVE, npm ELIFECYCLE, Python ModuleNotFoundError.
Related
Error: Cannot find module (Node)
Questions
What does Module not found: Can't resolve mean?
The bundler/Node resolver could not map your import string to a file or package on disk.
Why does it work on my Mac but fail in CI?
macOS filesystems are often case-insensitive; Linux is not. Fix the import/filename casing.
Do I need to restart the dev server?
After adding packages, changing aliases, or renaming files — yes. Stale resolve caches are common.
TypeScript finds the module but Next/webpack does not?
tsconfig paths alone don’t always configure the bundler. Add a matching alias or rely on Next’s built-in path support with a correct baseUrl.
What about ERR_MODULE_NOT_FOUND in Node?
Same idea at runtime: missing package, wrong path, or ESM import missing a file extension.
Is this the same as Python ModuleNotFoundError?
Same class of mistake (bad name/path/env), different toolchain. See the Python guide for venv/pip issues.
Published .