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 / clueLikely causeFix
Can't resolve './Foo'Wrong relative path or missing extensionCheck folder; on ESM you may need .js; try ../ levels carefully
Works on macOS, fails on Linux CICase mismatch (Button vs button)Rename to exact case; enable case-sensitive checks locally
Can't resolve 'some-pkg'Not installed / wrong workspacenpm i some-pkg (or pnpm/yarn); check it is in this package’s package.json
Can't resolve '@/…'Path alias only in TypeScriptMirror alias in next.config / Vite resolve.alias / webpack
Package has exports mapImporting a blocked subpathUse the documented export; avoid deep pkg/dist/… imports
Monorepo package nameWorkspace not linkedCheck workspaces, run install from root, verify package name field
ERR_MODULE_NOT_FOUND for relative fileNode ESM needs full extensionImport ./file.js even if source is .ts (emit path)
CSS / image / font importLoader / asset config missingConfirm bundler handles that extension; check public/ vs import

Checklist (fast)

  1. Read the path after Can't resolve and the in '…' directory — resolve it by hand from that folder.
  2. Confirm the file exists with the exact casing Linux will see.
  3. For bare specifiers (react, lodash): is it listed and is node_modules present? Delete lock + reinstall only as a last resort after checking the right package folder in a monorepo.
  4. For @/ or ~/ aliases: grep both tsconfig.json paths and the bundler config.
  5. 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

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 .

Try it

Related guides

Newest guides