TL;DR: The
Module not found: Can't resolveerror means Webpack couldn’t locate a module you imported. Runnpm install <missing-package>from your project root first. If that fails, deletenode_modulesand your lockfile, reinstall, then check yourwebpack.config.jsresolve settings and import paths. All scenarios are covered below.
Tested On: Node.js 18.x / 20.x · Webpack 4 and 5 · Create React App 5.x · Next.js 13/14 · React 17/18
What Does “Module Not Found: Can’t Resolve” Mean?
When you run or build your React app, Webpack reads every import and require() statement in your codebase to build a dependency graph. If it hits a module name it can’t find on disk — whether that’s a package from node_modules or a local file — it throws:
Module not found: Error: Can't resolve 'module-name' in '/your/project/src'
This is a build-time error, not a runtime one. Your app won’t compile until it’s fixed.
The error message tells you two things:
- The module it couldn’t find — e.g.,
react-router-dom - The file that triggered it — e.g.,
/your/project/src/App.js
Read both parts before jumping to fixes. Most wasted time on this error comes from skipping this step.
Root Causes
Most articles stop at “just run npm install.” There are at least nine distinct reasons this error occurs, and knowing which one applies changes the fix entirely.
| # | Cause | Common Trigger |
|---|---|---|
| 1 | Package not installed | Fresh clone, new import added |
| 2 | Wrong install directory | Monorepo, nested app folders |
| 3 | Corrupted node_modules | Switching package managers mid-project |
| 4 | Case sensitivity mismatch | Windows dev, Linux deploy |
| 5 | Bad Webpack resolve config | Ejected CRA, custom Webpack setup |
| 6 | Version conflict | Post-upgrade breakage |
| 7 | Wrong import path | ./react instead of react |
| 8 | TypeScript aliases not in Webpack | tsconfig.json paths not mirrored |
| 9 | Peer dependencies missing | Package requires unlisted peers |
How to Diagnose Before You Fix
Before running any commands, read the error carefully:
Module not found: Error: Can't resolve 'react-router-dom'
in '/Users/yourname/project/src/components'
What to look for:
- No
./or../prefix → it’s a package fromnode_modules. Go to Fix #1. - Starts with
./or../→ it’s a local file path problem. Go to Fix #8. - Starts with
@→ it’s a scoped npm package (@scope/package). Use the full name in your install command. - The file path → open that file and find the exact import line causing the error.
Fix #1: Install the Missing Package
The most common fix. Run from your project root — the folder that contains package.json:
| |
After installing, restart your dev server. If the error continues, confirm the package name in your import matches exactly what was installed, including any @scope/ prefix.
Fix #2: Check You’re in the Right Directory
In a monorepo or nested project where the React app lives in a subfolder (e.g., /frontend), running npm install from the wrong level puts the package in the wrong node_modules.
| |
Webpack resolves modules relative to your webpack.config.js location, not your terminal’s current directory. Verify that node_modules sits at the same level as package.json and webpack.config.js.
Fix #3: Clear and Reinstall node_modules
If packages appear to be installed but the error persists, node_modules may be corrupted or in a mixed state from switching package managers.
npm:
| |
yarn:
| |
pnpm:
| |
Windows (PowerShell):
| |
Fix #4: Fix Webpack’s Resolve Configuration
This is the fix most articles skip — and it’s responsible for a large share of the open issues on StackOverflow and GitHub for this exact error.
Webpack uses the resolve block in webpack.config.js to know where to look for modules and which file extensions to try. A misconfigured resolve block makes Webpack fail even when packages are correctly installed.
The Problem
| |
The Fix
| |
Webpack 4 → 5 Migration
Webpack 5 removed automatic Node.js core module polyfills. If your project or any dependency uses crypto, buffer, stream, or path, add explicit fallbacks:
| |
Install the corresponding packages:
| |
Fix #5: Handle Case Sensitivity Errors
If the error only shows up in CI/CD or on a Linux server — not on your local Windows or macOS machine — case sensitivity is almost certainly the cause.
Windows file systems are case-insensitive. Linux file systems are not. An import that works locally can fail on every Linux-based deployment target.
| |
Fix the import to match the filename exactly. To catch these locally before they reach production, install:
| |
| |
Fix #6: Fix TypeScript Path Aliases
If you’ve set up path aliases in tsconfig.json like @components/Button, TypeScript understands them — Webpack does not. They’re separate tools with separate resolvers. You have to wire aliases up in both places.
tsconfig.json
| |
webpack.config.js (manual mirror)
| |
Automatic sync with tsconfig-paths-webpack-plugin
To keep both files in sync automatically without manually maintaining aliases in two places:
| |
| |
Fix #7: Resolve Peer Dependency and Version Conflicts
If the error appeared after upgrading a package, a version conflict is the likely cause. Inspect the dependency tree first:
| |
If you see multiple versions or UNMET PEER DEPENDENCY warnings, here are your options:
Option A — --legacy-peer-deps (quick fix, use with caution)
| |
Option B — overrides in package.json (npm 8.3+)
| |
Option C — resolutions in package.json (yarn)
| |
Fix #8: Check Your Import Statements
Sometimes the package is installed and Webpack is configured correctly, but the import itself is wrong.
| |
Version mismatches are common with react-router-dom after upgrading from v5 to v6:
| |
Always verify your import syntax against the installed version, especially after major upgrades.
Common Scenarios
Can’t Resolve react-router-dom
| |
If you’re upgrading from v5 to v6, the install alone won’t fix it. Switch is now Routes, route definitions changed, and nested routes work differently. A mismatch between your code and the installed version is often the real cause, not a missing package.
Can’t Resolve react in Next.js
Usually means you’re outside the project directory, or react was installed at the monorepo root while Next.js is looking in the package subfolder. Check:
| |
If nothing returns, run npm install from the correct directory. Also confirm react and react-dom are in dependencies, not devDependencies.
Can’t Resolve a Local File or Component
| |
Verify the file exists with that exact name and extension. Webpack needs the extension listed in resolve.extensions, or included directly in the import path. If importing a folder, ensure it contains an index.js or index.tsx.
Can’t Resolve After Upgrading Webpack (v4 to v5)
Webpack 5 removed automatic Node.js polyfills. If your project or any dependency uses crypto, buffer, stream, or path, they’ll fail to resolve. Add polyfills via resolve.fallback as shown in Fix #4.
Can’t Resolve in Docker or CI/CD
The most common cause: node_modules is not being built inside the container, or the COPY step runs before npm install.
| |
Also check that .dockerignore is not excluding package.json or package-lock.json.
How to Prevent This Error
Commit your lockfile. package-lock.json or yarn.lock ensures every developer and CI environment installs the same versions. Don’t add it to .gitignore.
Use one package manager per project. Mixing npm and yarn corrupts lockfiles and causes inconsistent installs. Pick one and document it in your README.
Add an engines field. This prevents problems caused by team members running different Node versions:
| |
Use eslint-plugin-import. Catches broken imports, missing packages, wrong paths, and case errors at lint time — before the build runs.
Run CI builds on Linux. Local macOS development hides case-sensitivity bugs. A Linux CI step catches them before they reach production.
Quick Reference: Diagnosis Checklist
| Symptom | Likely Cause | Fix |
|---|---|---|
| Error on fresh clone | Package not installed | npm install from project root |
| Error only in CI / production | Case sensitivity mismatch | Fix filename case; add CaseSensitivePathsPlugin |
| Error after switching branches | Dependency missing in that branch | npm install |
| Error in a monorepo | Wrong install directory | Run install from the app subfolder |
| Error after a package upgrade | Version conflict or broken import syntax | npm ls <package>; update imports |
Error with @alias imports | TypeScript paths not in Webpack | Add resolve.alias or TsconfigPathsPlugin |
| Error with Node core modules | Webpack 5 removed polyfills | Add resolve.fallback entries |
| Error with a local file import | Wrong path, extension, or filename case | Verify file exists with exact name |
| Clean install still fails | Corrupted node_modules | Delete node_modules + lockfile, reinstall |
| Error in Docker / CI only | node_modules not installed in container | Fix Dockerfile layer order |
Conclusion
The Module not found: Can't resolve error in React and Webpack is almost always fixable in a few minutes once you know what’s causing it. Read the error message, match the symptom to a cause, and apply the right fix — rather than blindly running npm install and hoping.
The two fixes most articles miss are the Webpack resolve configuration (especially during Webpack 4-to-5 migrations) and the TypeScript path alias gap. These two account for a disproportionate share of unresolved threads on GitHub and StackOverflow for this exact error.
FAQ
Why does the error appear after I pull from Git?
node_modules is never committed to Git. When someone adds a new dependency, you need to run npm install locally to get it. Always run npm install after pulling if you see this error.
Can this error appear even if the package is in package.json?
Yes. Being listed in package.json doesn’t mean it’s installed. The node_modules folder is what matters at build time. Run npm install to sync them.
Why does it work on my machine but fail on the server?
Almost always a case sensitivity issue (Windows/macOS vs. Linux) or node_modules not being installed in the server or container environment. See Fix #5 and the Docker scenario above.
Does this error happen with Vite too?
Yes. Vite has its own module resolver, but the root causes are identical: missing packages, wrong paths, case sensitivity, and alias misconfiguration. The diagnosis steps are the same; the config file is vite.config.js instead of webpack.config.js.
What’s the difference between dependencies and devDependencies here?
Runtime packages like react, react-dom, and react-router-dom should be in dependencies. Putting them in devDependencies can cause them to be excluded in certain production build setups, producing this error in production but not in development.
Why does deleting node_modules and reinstalling fix things that npm install alone doesn’t?
npm install adds missing packages but won’t clean up corrupted or conflicting ones already in node_modules. A clean reinstall removes everything and rebuilds the dependency tree from scratch.