Error: Cannot find module '...' (code: MODULE_NOT_FOUND) when require() cannot locate the requested file or package. The most common fix is running npm install if you just cloned a repo, or checking for a typo in the module name or file path.
What is "Error: Cannot find module"?
Error: Cannot find module '...' is the most frequently encountered
Node.js error. It is thrown by the
CommonJS module loader
whenever require() cannot resolve the string you passed — whether that is an npm
package name, a relative file path, or a built-in module alias that does not exist.
The error object carries the code MODULE_NOT_FOUND.
Error: Cannot find module 'express'Error: Cannot find module './utils'Error: Cannot find module '@/components/Button'Error: Cannot find module './config.json'Error: Cannot find module './models'
Full Error Example
node:internal/modules/cjs/loader:1039
throw err;
^
Error: Cannot find module 'express'
Require stack:
- /project/app.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1039:15)
at Function.Module._load (node:internal/modules/cjs/loader:885:27)
at Module.require (node:internal/modules/cjs/loader:1105:19)
at require (node:internal/modules/cjs/helpers:103:18)
at Object.<anonymous> (/project/app.js:1:17) {
code: 'MODULE_NOT_FOUND',
requireStack: [ '/project/app.js' ]
}
The Require stack field (added in Node.js 12) shows the chain of files that
triggered the failing require(), which is invaluable for tracing the source of
the error in large projects.
Root Cause
When you call require('some-module'), Node.js runs its
module resolution algorithm:
- If the string starts with
./,../, or/— resolve as a file path relative to the current file. - Otherwise — walk up
node_modules/directories starting from the current file's location. - If nothing is found at any step — throw
MODULE_NOT_FOUND.
The error fires whenever the algorithm reaches the end of its search without finding a match.
All Causes at a Glance
| Cause | Typical symptom | Quick fix |
|---|---|---|
| Dependencies not installed | Cannot find module 'express' after cloning |
npm install |
| Typo in module name | Cannot find module 'loadash' |
Fix the spelling in require() |
| Wrong relative path | Cannot find module './utils' (wrong directory level) |
Adjust ./ / ../ prefix |
| Missing file extension | Cannot find module './config' for a JSON file |
Use require('./config.json') |
| Missing index.js | Cannot find module './models' (directory import) |
Create models/index.js |
| Global-only install | Cannot find module 'typescript' (installed with -g) |
npm install typescript locally |
| devDependency in production | Works locally, fails on server | Move to dependencies |
| ESM-only package with require() | Cannot find module 'chalk' (chalk@5+) |
Use await import('chalk') or downgrade |
| Case sensitivity on Linux | Works on macOS/Windows, fails on Linux/CI | Match filename case exactly |
| Corrupted node_modules | Package appears installed but error persists | rm -rf node_modules && npm install |
| TypeScript path aliases | Cannot find module '@/utils' at runtime |
Register tsconfig-paths |
| Docker — no local install | Cannot find module 'express' in container |
Run npm install in Dockerfile |
| Wrong working directory | Script runs from wrong directory | cd to project root first |
| Broken symlinks | Error after linking packages or using workspaces | rm -rf node_modules && npm install |
Common Causes & Fixes
Cause 1 – Dependencies not installed
The most frequent cause: you cloned a repo or switched branches and node_modules is missing or out of date.
# Install all dependencies listed in package.json
npm install
# Or with yarn / pnpm
yarn install
pnpm install
express, dotenv, axios,
lodash, typescript, @prisma/client, react,
next, jest — any package will trigger this if node_modules is absent.
Cause 2 – Typo in the module name
npm package names are case-sensitive and exact. A single character difference silently produces this error.
// Wrong
const express = require('Express'); // capital E
const lodash = require('loadash'); // missing 'd'
// Correct
const express = require('express');
const lodash = require('lodash');
Cause 3 – Wrong relative path
Relative paths are resolved from the current file's location, not the project root.
// File: /project/src/routes/users.js
// Trying to import /project/src/utils.js
// Wrong – resolves to /project/src/routes/utils.js (not found)
const utils = require('./utils');
// Correct
const utils = require('../utils');
Use console.log(__dirname) or path.resolve('./utils') to debug the resolved path at runtime.
const path = require('path');
console.log(path.resolve('./utils')); // prints the full path Node.js will look up
Cause 4 – Missing file extension for non-JS files
Node.js automatically tries .js, .json, and .node extensions
when resolving bare filenames — but only in that order and only when no extension is given for a
relative path. In practice, omitting the extension for .json files can silently fail
in certain configurations or when the file does not exist with the expected name.
// Wrong – may throw MODULE_NOT_FOUND if resolution fails
const config = require('./config');
// Correct – always explicit for non-JS files
const config = require('./config.json');
const native = require('./bindings.node');
Cause 5 – Missing index.js for directory imports
When you require('./models') and models is a directory, Node.js looks
for models/index.js. If that file does not exist, you get MODULE_NOT_FOUND.
// Directory structure that causes the error:
// models/
// User.js
// Post.js
// (no index.js)
const models = require('./models'); // throws MODULE_NOT_FOUND
// Fix: create models/index.js
const User = require('./User');
const Post = require('./Post');
module.exports = { User, Post };
Cause 6 – Package installed globally, not locally
Running npm install -g express makes express available as a CLI tool
but does not make it available to require() inside your project. Node.js
searches node_modules/ directories relative to the script — not the global npm prefix.
# This does NOT fix the error
npm install -g express
# This does fix the error
npm install express
# Verify local installation
npm ls express
Cause 7 – Running from the wrong working directory
Node.js resolves bare module names by searching node_modules/ starting from the
script's location, but ./ paths are relative to process.cwd(). Running
a script from a parent directory changes what ./ resolves to.
# Wrong – running from the parent directory
cd /
node project/src/app.js
# Correct
cd /project
node src/app.js
Always run node from the project root, or use __dirname-based absolute paths in your code.
Cause 8 – Package in devDependencies used in production
npm install --production (or NODE_ENV=production npm install) skips
devDependencies. If a package required at runtime lives there, it will be missing
in production.
// Move from devDependencies to dependencies in package.json
{
"dependencies": {
"dotenv": "^16.0.0" // ← was incorrectly in devDependencies
}
}
Cause 9 – ESM-only package loaded with require()
Several popular npm packages dropped CommonJS support and published ESM-only versions.
Using require() on these packages throws MODULE_NOT_FOUND or
ERR_REQUIRE_ESM
(depending on Node.js version).
Common ESM-only packages: chalk@5+, node-fetch@3+, got@12+, ora@6+, p-limit@4+, execa@6+
// Wrong – chalk v5 is ESM-only
const chalk = require('chalk'); // Error: Cannot find module 'chalk'
// Fix option 1 – use dynamic import (works in any .js file)
const chalk = await import('chalk');
// Fix option 2 – downgrade to last CJS version
// npm install chalk@4
const chalk = require('chalk'); // chalk@4 is CJS
// Fix option 3 – convert project to ESM
// Add "type": "module" to package.json and use import syntax
import chalk from 'chalk';
Cause 10 – Case sensitivity on Linux
macOS and Windows filesystems are usually case-insensitive, so require('./Utils')
finds utils.js. Linux (including most CI/CD and production servers) is
case-sensitive — the same code throws Cannot find module.
// Wrong on Linux (file on disk is utils.js)
const utils = require('./Utils');
// Correct – match the filename exactly
const utils = require('./utils');
Cause 11 – Corrupted or incomplete install
Interrupted installs, disk errors, or npm cache corruption can leave node_modules in a broken state even though the package appears in package.json.
# macOS / Linux – full clean reinstall
rm -rf node_modules package-lock.json
npm install
# Windows (Command Prompt)
rd /s /q node_modules
del package-lock.json
npm install
# Optional: also clear the npm cache
npm cache clean --force
npm install
Cause 12 – TypeScript path aliases not resolved at runtime
TypeScript supports path aliases like @/utils or ~/components defined
in tsconfig.json. These are a TypeScript-only feature — the compiled JavaScript
still contains the alias string, and Node.js has no idea what @/utils means.
// tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": { "@/*": ["src/*"] }
}
}
// your code – works in TypeScript, throws Cannot find module at runtime
import { helper } from '@/utils';
Fix: register tsconfig-paths at runtime to teach Node.js how to resolve the aliases:
# compiled output
node -r tsconfig-paths/register dist/app.js
# with ts-node
ts-node -r tsconfig-paths/register src/app.ts
Alternatively, use a bundler (esbuild, webpack, Vite) that resolves aliases at build time so no runtime registration is needed.
Cause 13 – node_modules not installed inside Docker
A common Docker mistake: installing dependencies on the host machine and then copying the whole
project into the image. If node_modules is in .dockerignore
(as it should be), dependencies will be missing unless npm install runs inside
the container.
# Wrong Dockerfile order
COPY . .
RUN npm install # too late — node_modules from host was never copied in
# Correct – install before copying source; exploits layer cache too
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "src/app.js"]
Also confirm your .dockerignore includes node_modules so the host modules are never copied into the image.
Cause 14 – Broken symlinks in node_modules
npm workspaces, npm link, and some CI environments create symlinks inside
node_modules. If the symlink target no longer exists or the symlink was corrupted,
Node.js cannot follow it and throws MODULE_NOT_FOUND.
# Detect broken symlinks (macOS/Linux)
find node_modules -type l ! -exec test -e {} \; -print
# Fix: full reinstall
rm -rf node_modules package-lock.json
npm install
# If using npm workspaces, run from the workspace root
npm install --workspaces
Debugging Techniques
Inspect the module search paths
module.paths is an array of every node_modules directory Node.js will
search, in order. Print it to verify Node.js is looking in the right place.
// Add temporarily to the failing script
console.log(module.paths);
// [
// '/project/src/node_modules',
// '/project/node_modules',
// '/node_modules'
// ]
Use require.resolve() to test resolution
try {
const resolved = require.resolve('express');
console.log('Found at:', resolved);
} catch (err) {
console.error('Not found:', err.message);
}
Enable Node.js module debug output
# Prints every path Node.js attempts during resolution
NODE_DEBUG=module node app.js
General debugging checklist
- Read the
Require stackin the error — it shows exactly which file calledrequire(). - Run
ls node_modules/<package-name>to confirm the package is physically installed. - Run
npm ls <package-name>to see if it is listed as a dependency. - Print
__dirnameandpath.resolve('./your-path')to verify the resolved path. - Print
module.pathsto see all directories Node.js is searching. - Check
package.json— is the package underdependenciesordevDependencies? - Confirm the filename on disk matches the case used in
require(). - In TypeScript projects, check for unresolved path aliases in the compiled output.
- In Docker/CI, confirm
npm installruns inside the container, not just on the host. - Run
NODE_DEBUG=module node app.jsto trace every path attempted during resolution.
CJS vs ESM: MODULE_NOT_FOUND vs ERR_MODULE_NOT_FOUND
The MODULE_NOT_FOUND code belongs to the CommonJS (require()) loader.
The native ESM (import) loader throws a different error code:
ERR_MODULE_NOT_FOUND. The root causes are identical but the error messages look different:
| Loader | Error code | Typical message |
|---|---|---|
CommonJS (require) |
MODULE_NOT_FOUND |
Error: Cannot find module 'x' |
ESM (import) |
ERR_MODULE_NOT_FOUND |
Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'x' |
node_modules without also deleting
package-lock.json can leave npm in an inconsistent state. Always delete both before
a clean reinstall.
Frequently Asked Questions
What does "Error: Cannot find module" mean in Node.js?
Error: Cannot find module (error code MODULE_NOT_FOUND) is thrown by the
Node.js CommonJS module loader when require() cannot resolve the requested module name
or file path. This error occurs both for missing npm packages and for incorrect relative file paths.
Since Node.js 12, the error includes a requireStack array showing exactly which files
triggered the failing require().
Why does "Cannot find module" happen even after npm install?
Several reasons the error can persist after running npm install:
- You ran
npm installin a different directory than where you run the script. - The package is in
devDependenciesand you rannpm install --production. - The install was corrupted — delete
node_modulesandpackage-lock.jsonand reinstall. - The package was installed globally with
-ginstead of locally. - A lockfile version mismatch caused the package to not resolve correctly.
How do I fix "Cannot find module" for an ESM-only package like chalk@5?
Packages like chalk@5, node-fetch@3, got@12, and
ora@6 are ESM-only and cannot be loaded with require(). You have three options:
- Use a dynamic import:
const chalk = await import('chalk'); - Downgrade to the last CJS version:
npm install chalk@4 - Convert your project to ESM: add
"type": "module"topackage.jsonand useimportsyntax throughout.
How do I fix "Cannot find module" for a directory import?
When you require('./models') and models is a directory, Node.js looks
for models/index.js. If that file does not exist, you get MODULE_NOT_FOUND.
Create an index.js inside the directory that exports the intended values:
// models/index.js
const User = require('./User');
const Post = require('./Post');
module.exports = { User, Post };
How do I fix "Cannot find module" in TypeScript projects?
In TypeScript projects, Cannot find module at runtime is usually caused by path
aliases (e.g. @/utils) defined in tsconfig.json that are not resolved
by Node.js at runtime. Fix it by registering tsconfig-paths:
node -r tsconfig-paths/register dist/app.js
# or with ts-node:
ts-node -r tsconfig-paths/register src/app.ts
Alternatively use a bundler (esbuild, webpack, Vite) that resolves aliases at build time.
How do I fix "Cannot find module" inside a Docker container?
In Docker, this error almost always means npm install did not run inside the container.
Structure your Dockerfile to copy package.json first, then install, then copy source:
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "src/app.js"]
Also make sure node_modules is listed in your .dockerignore file.
How do I debug which paths Node.js is searching for a module?
Three useful techniques:
- Print
module.pathsto see everynode_modulesdirectory searched, in order. - Use
require.resolve('module-name')— returns the full resolved path on success, or throws a detailed error on failure. - Run
NODE_DEBUG=module node app.jsto trace every path Node.js attempts during resolution.
Works on macOS but fails on Linux — why?
macOS and Windows use case-insensitive filesystems by default, so require('./Utils')
successfully loads utils.js. Linux uses a case-sensitive filesystem — the same
require('./Utils') throws Cannot find module because there is no file
named Utils.js. Fix: match the exact case of the filename in every require()
or import statement. Linters like eslint-plugin-import can catch this automatically.
Related Errors
ERR_REQUIRE_ESM– the package exists but is ESM-only and must be loaded withimport(), notrequire()ERR_PACKAGE_PATH_NOT_EXPORTED– the package is installed but the subpath you import is not in itsexportsmapSyntaxError: Cannot use import statement in a module– ESM/CJS mismatch in the other directionENOENT: no such file or directory– a related filesystem-level error for missing files