Next.js Module not found: Can't resolve 'X'
Encountering "Module not found: Can't resolve 'X'" means Next.js cannot locate an imported dependency; this guide explains how to fix it with practical steps.
What This Error Means
When Next.js throws a "Module not found: Can't resolve 'X'" error, it indicates that the Webpack compiler, which Next.js uses internally, failed to locate a module or file that you're attempting to import. The 'X' in the error message will be the specific path or package name that could not be resolved. This can happen during npm run dev (development server), npm run build (production build), or npm run start (production server runtime if the module is dynamically imported server-side).
Essentially, your code is asking for something that isn't where Next.js expects it to be, or perhaps doesn't exist at all within the project's accessible paths. It's a critical error because the application cannot compile or run without all its required modules.
Why It Happens
Module resolution is a core part of how JavaScript applications work, especially in environments like Node.js and client-side bundlers like Webpack. When you write import SomeModule from 'path/to/SomeModule' or import SomePackage from 'some-package', the module resolver follows a set of rules to find that module.
For local files, it looks at relative paths (./, ../) or absolute paths defined by configuration (like baseUrl or paths in tsconfig.json/jsconfig.json). For installed packages, it typically checks the node_modules directory, searching for the package name and then its entry point (defined in the package's package.json).
This error occurs when one of these resolution attempts fails. In my experience, it's often a simple oversight, but it can sometimes point to more complex configuration issues, especially in larger projects or monorepos.
Common Causes
Based on my experience as a Platform Engineer, these are the most frequent reasons I've encountered for the "Module not found" error in Next.js applications:
- Typos in Import Paths or Package Names: The most straightforward cause. A misspelled filename, directory name, or package name will prevent the resolver from finding the target.
- Missing or Uninstalled Node Module: If you
import 'some-package'butsome-packageisn't listed in yourpackage.jsondependencies or hasn't been installed (e.g.,npm installoryarn installwasn't run), Next.js won't find it innode_modules. - Incorrect Relative Paths: Misjudging the current file's location relative to the imported file (e.g.,
../vs./vs../../). This is particularly common when refactoring files. - Absolute Path Configuration Issues: If you're using absolute imports (e.g.,
import Button from '@/components/Button'), the aliases defined intsconfig.json(for TypeScript) orjsconfig.json(for JavaScript) might be incorrect, missing, or not correctly understood by Next.js. - Case Sensitivity Mismatches: File systems on macOS and Windows are often case-insensitive by default, while Linux (common in CI/CD, Docker, and production servers) is case-sensitive.
components/Button.tsxandComponents/Button.tsxare different files on Linux. If your local dev environment toleratesimport Button from './components/button', but the actual file isButton.tsx, it will break in a Linux build environment. This is a classic "works on my machine" scenario. - Caching Issues: Sometimes, stale caches (
.next/,node_modules/) can confuse the module resolver, especially after adding new dependencies or refactoring. - Monorepo / Workspace Complications: In a monorepo, packages might be symlinked. If the root
node_modulesisn't correctly structured ornext.config.jsisn't configured withtranspilePackagesfor local packages, Next.js might fail to resolve or transpile modules. - Client-side Import of Node.js-only Modules: Next.js uses Webpack to bundle client-side code. If you try to
import 'fs'(Node.js File System module) directly into a component rendered on the client, Webpack will fail because 'fs' is not available in the browser environment. - Next.js Specific
transpilePackagesorserverComponentsExternalPackagesMisconfiguration: For packages that need to be transpiled (e.g., ESM-only packages in a CJS context or internal monorepo packages),transpilePackagesinnext.config.jsis crucial. Similarly,serverComponentsExternalPackageshelps manage server components.
Step-by-Step Fix
Here’s my go-to troubleshooting process when I encounter a "Module not found" error:
-
Verify the Import Path and Module Name (Critical First Step):
- Double-check spelling: Is 'X' in the error message exactly what you intended to import?
- Relative vs. Absolute: If it's a relative path (e.g.,
./components/Button), manually trace the path from the importing file to the target file. Ensure all slashes and directory names are correct. If it's an absolute path (e.g.,@/components/Button), verify the alias configuration (see step 4). - Case Sensitivity: Ensure the casing of the import path exactly matches the actual file/folder names on disk. This is especially important if you're developing on macOS/Windows and deploying to Linux.
-
Check
package.jsonandnode_modules:- If 'X' is a third-party package name (e.g.,
lodash,react-query), confirm it's listed underdependenciesordevDependenciesin yourpackage.json. -
If it is, try re-installing your dependencies:
```bash
# For npm
rm -rf node_modules
npm installFor yarn
rm -rf node_modules
yarn installFor pnpm (if applicable)
pnpm recursive install # or pnpm install -r
`` * After installation, verify that the package's folder exists innode_modules/X`.
- If 'X' is a third-party package name (e.g.,
-
Clear Next.js and Node Caches:
- Stale build artifacts or module caches can sometimes cause these issues.
- Stop your development server (
Ctrl+C). - Remove the Next.js build cache and
node_modules:
bash rm -rf .next rm -rf node_modules - Reinstall dependencies and restart the development server:
bash npm install # or yarn install / pnpm install npm run dev
-
Review
tsconfig.json/jsconfig.jsonfor Path Aliases:- If you're using absolute imports (e.g.,
import MyComponent from '@/components/MyComponent'), ensure yourbaseUrlandpathsare correctly configured. - For TypeScript, open
tsconfig.json. For JavaScript, openjsconfig.json. - Look for the
compilerOptionssection:
json { "compilerOptions": { "baseUrl": ".", // This usually means root of your project "paths": { "@/*": ["./*"], // This maps "@/" to your project root "@components/*": ["components/*"] // Example for specific alias } } } - Adjust
baseUrlandpathsto correctly point to your desired directories. I've often seenbaseUrlpointing tosrcwhile imports were trying to resolve from root, causing confusion.
- If you're using absolute imports (e.g.,
-
Examine
next.config.js:- If you're dealing with a monorepo, an external UI library, or packages that need specific Webpack treatment,
transpilePackagesmight be necessary. -
```javascript
/* @type {import('next').NextConfig} /
const nextConfig = {
reactStrictMode: true,
transpilePackages: ['some-ui-library', 'my-local-package'], // Add packages here
// ... other configs
};module.exports = nextConfig;
`` * If you're importing a Node.js-only module in a Server Component, you might need to externalize it or mark it for specific handling usingserverComponentsExternalPackages`.
- If you're dealing with a monorepo, an external UI library, or packages that need specific Webpack treatment,
-
Identify Node.js Built-in Module Imports:
- If 'X' is a Node.js built-in module like
fs,path,crypto,http, and the error occurs in a client-side component, it means you're trying to use server-only functionality in the browser. - Solution:
- Move the logic that uses these modules to an API route, a server component, or a server-side utility function.
- If the module has a browser-compatible polyfill, consider using that (though this is less common with Next.js's server-side rendering).
- Use dynamic imports (
await import('...')) withssr: falseto ensure it's only loaded client-side if a polyfill exists or if the browser environment supports it.
- If 'X' is a Node.js built-in module like
-
Restart Your Development Server: After making any changes, always restart your development server (
npm run dev) to ensure Webpack recompiles with the new configurations.
Code Examples
Here are some concise, copy-paste ready examples for common scenarios:
1. Correct Relative Import:
Suppose you have pages/index.tsx and components/Button.tsx.
pages/index.tsx:
import Button from '../components/Button'; // Correct relative path from pages/ to components/
export default function HomePage() {
return <Button>Click me</Button>;
}
2. Absolute Import with tsconfig.json:
To enable imports like import Button from '@/components/Button';
tsconfig.json:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./*"] // Maps @/ to the project root
},
// ... other compiler options
},
// ...
}
pages/index.tsx:
import Button from '@/components/Button'; // Assuming components/Button.tsx exists at project root/components/Button.tsx
export default function HomePage() {
return <Button>Click me</Button>;
}
3. next.config.js for Transpiling Local Packages (Monorepo):
If my-local-package is a package within your monorepo that Next.js needs to transpile.
next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
transpilePackages: ['my-local-package'],
};
module.exports = nextConfig;
4. Handling Node.js Built-in Modules on the Server:
If you need to read a file, do it in a server component or API route.
app/page.tsx (Server Component):
import { promises as fs } from 'fs'; // This import will only run on the server
export default async function HomePage() {
let content = '';
try {
content = await fs.readFile(process.cwd() + '/public/data.txt', 'utf8');
} catch (error) {
console.error('Failed to read file:', error);
}
return (
<div>
<h1>File Content:</h1>
<pre>{content}</pre>
</div>
);
}
Environment-Specific Notes
The "Module not found" error can manifest differently or be caused by unique factors depending on your deployment environment.
-
Local Development: This is where you'll typically first encounter the error due to typos, new package installations, or minor path changes. The key here is quick iteration: restarting the dev server, clearing caches (
.next,node_modules), and double-checking file paths andtsconfig.json. Case sensitivity is less of an issue here unless you've configured your local system to be case-sensitive. -
Docker Containers: When building or running Next.js in a Docker container, I've seen this error primarily because:
- Incorrect
COPYinstructions in Dockerfile:node_modulesmight not be copied correctly, or the build context might be wrong. Ensure yourCOPY . .happens afternpm installand that your.dockerignoreisn't inadvertently excluding essential files or directories. - Different OS: The Docker image likely runs Linux. This makes case sensitivity a significant factor if your local development was on macOS or Windows. Always match case precisely.
- Build-time vs. Runtime: Some modules might resolve fine during
npm run buildin a builder stage but then fail at runtime if the runtime image doesn't have the necessary dependencies or environment variables.
- Incorrect
-
Cloud Platforms (Vercel, AWS Amplify, Netlify): These platforms often abstract away much of the build environment, but they run on Linux-based systems.
- Case Sensitivity: This is the most common culprit when "it works on my machine" but fails in CI/CD.
- Build Command Issues: Ensure your build command (
next build) runs successfully and that all dependencies are installed. Sometimes platforms useyarnby default, but your project might expectnpm. Configure the correct package manager if necessary. - Monorepo Configuration: For Vercel, ensuring your project root and included files are correctly configured in
vercel.jsonor the Vercel UI is crucial, especially for monorepos where Next.js apps might be nested. Similarly for AWS Amplify, ensuring correct build settings and artifact paths is key. - Environment Variables: If a module's resolution depends on an environment variable (e.g., for conditional imports or pathing), ensure that variable is correctly set in the cloud build environment.
Frequently Asked Questions
Q: Why does my project build locally but fail with "Module not found" in CI/CD?
A: This is almost always a case sensitivity issue or a difference in the build environment. Locally, your file system might be case-insensitive, but CI/CD environments (typically Linux) are case-sensitive. Double-check all file and directory names in your import paths for exact case matches. Also, ensure all node_modules are correctly installed in the CI/CD pipeline, and clear any potential caches.
Q: What if 'X' is a CSS, SCSS, or image file?
A: If it's a styling or asset file, the "Module not found" error usually indicates a wrong path or a missing Webpack loader configuration.
* Path: Verify the import path is correct, just like for JavaScript/TypeScript files.
* Loader: Ensure you have the necessary Next.js configuration or Webpack loaders (e.g., sass for SCSS, css for CSS, Next.js handles images by default but next/image requires specific setup). For example, npm install sass is needed for SCSS.
Q: How do baseUrl and paths work together in tsconfig.json / jsconfig.json?
A: baseUrl defines the base directory from which all non-relative module imports are resolved. paths allows you to create aliases that map specific module names or patterns to a set of locations, relative to the baseUrl. For example, baseUrl: "./" and paths: { "@/*": ["src/*"] } would mean import Some from '@/util/Some' would look for src/util/Some from the project root.
Q: Can this error be related to next.config.js?
A: Absolutely. As mentioned, transpilePackages is crucial for monorepos or specific packages. Additionally, custom Webpack configurations within next.config.js (webpack function) can inadvertently break module resolution if not handled carefully. For instance, modifying default resolution rules can lead to conflicts.
Q: I'm getting "Module not found: Can't resolve 'fs'" (or similar Node.js modules) in a client-side component. How do I fix this?
A: This means you're trying to import a Node.js built-in module, like the file system (fs), directly into code that Next.js intends to run in the browser. These modules are not available in browser environments. You must move any logic using these modules to server-side code (e.g., API routes, server components, or getServerSideProps/getStaticProps).