Corporate Software
How to fix a "Cannot find module" error: a step-by-step guide

Short answer
Read the module name or file path the error message points to first. Then check whether the module is actually installed (npm install), whether the name or path is spelled correctly, and whether a relative import under ECMAScript modules is missing its file extension.
In most cases, deleting node_modules and the lock file and reinstalling, fixing a wrong relative path, or rewriting TypeScript path aliases into real paths during the build resolves it within minutes.
Why the “Cannot find module” error happens
When Node.js runs a line like require('package-name') or import x from './file', it first tries to resolve that statement into an actual file path. It uses its own module resolution algorithm to do this. For a relative path, it looks at the folder structure on disk. For a package name, it walks up through node_modules folders, starting in the current directory and moving to parent directories if nothing is found there. If the expected file isn’t on disk anywhere in that chain, Node.js stops searching and prints a “Cannot find module” error to the terminal.
This error shows up most often in a handful of recurring situations. Starting an app right after cloning a repository, without running npm install first, is one. Removing a package from package.json but forgetting a reference to it still exists in the code is another. So is renaming a file or folder without updating the import paths that pointed to it, or carrying old require habits into import syntax while migrating from CommonJS to ECMAScript modules. The file path and error code underneath the message (MODULE_NOT_FOUND or ERR_MODULE_NOT_FOUND) point straight at the root cause. Skipping that line and reinstalling at random usually wastes more time than it saves.
Learn to read the terminal output
Node.js typically prints which file it tried to resolve and from where. A line like “Cannot find module ‘./utils/helpers’” shows both the directory it searched and the file name it was looking for. That detail lets you immediately tell whether the problem is a package or your own file. A package name points to a missing install. A relative path, one starting with ./ or ../, points to a mismatch on disk.
What are the most common “Cannot find module” scenarios?
| Scenario | Typical cause | First fix |
|---|---|---|
Error on a package name (require('package-name')) |
The package was never installed, or node_modules is missing it | Run npm install and verify the name in package.json |
Error on a relative path (./file or ../folder) |
The file was moved, renamed, or the path is misspelled | Compare the import path against the actual folder structure |
Error after import under ESM (ERR_MODULE_NOT_FOUND) |
A relative import is missing its file extension | Add .js or .mjs to the import path |
| Error after a TypeScript build | A tsconfig.json path alias is never resolved in the compiled output |
Add a converter like tsc-alias |
| Package not found in a monorepo | Wrong working directory, or a dependency-hoisting issue | Run npm install from the monorepo root |
| Works locally, fails in Docker/CI | node_modules wasn’t copied into the image, or .dockerignore excludes it |
Check the dependency install step in your Dockerfile |
How to fix a cannot find module error
The steps below go from lowest-risk to most thorough. After each one, rerun the app and check whether the error changes.
1. Verify the module name, spelling, and installation
If the error is about a package name, first check that it’s listed under dependencies or devDependencies in package.json. If it isn’t, add it with npm install package-name. If it is listed but you’re still getting the error, check whether that package actually exists inside node_modules. Sometimes an install gets interrupted, and package.json ends up up to date while the files were never written to disk. Node.js is also case-sensitive, so a typo like require('Lodash') triggers the same error even when the package name is almost right.
2. Rebuild node_modules and the lock file from scratch
An interrupted install or a corrupted cache is one of the most common causes. Deleting the node_modules folder and package-lock.json entirely, then running npm install from scratch, rebuilds the dependency tree. This doesn’t touch your source code; node_modules is always a fully regenerable folder. In a CI/CD pipeline, doing the same reset with npm ci gives a more reliable result because it takes the lock file as the single source of truth.
3. Apply ESM’s path and file-extension rules correctly
If package.json declares "type": "module", or your files use the .mjs extension, your project is using ECMAScript modules (ESM). Unlike CommonJS, ESM requires an explicit file extension on relative imports: import { helper } from './utils' doesn’t work under ESM, you need import { helper } from './utils.js'. Node.js’s official error reference documents this behavior in detail, along with the ERR_MODULE_NOT_FOUND code it produces. Bare imports (by package name, without an extension) aren’t affected by this rule; it only applies to relative paths pointing at your own files.
4. Fix TypeScript path-alias and tsconfig-related errors
If you’ve defined shortcuts like @/utils in tsconfig.json, that setting only guides the TypeScript compiler and your editor, for example VS Code. Once tsc compiles your code down to JavaScript, Node.js has no awareness of that alias at runtime and throws “Cannot find module ‘@/utils’”. The fix is adding a tool such as tsc-alias or tsconfig-paths to rewrite those aliases into real relative paths during the build step. Skip that step, and the code looks fine in your editor but breaks in production.
The “Cannot find module” error in Docker and deployment environments
An app that runs fine on your machine can throw the same error inside a Docker image or on a deployment platform such as Vercel, Railway, or your own server. The most common reason is that node_modules was never copied into the image, or that .dockerignore accidentally excludes it. Running the dependency install step (RUN npm ci) in its own layer before copying the source code shortens build times and reduces the risk of a missing install. In monorepos, a working directory that differs from the repository root can cause dependencies to install into the wrong folder. Always run npm install from the monorepo’s root directory.
How teams can reduce this error going forward
A “Cannot find module” error isn’t usually a one-off glitch; it’s typically a sign of a small inconsistency in dependency or import discipline. Teams that always commit package-lock.json to Git guarantee everyone builds the same dependency tree. Using your editor’s “rename symbol” feature whenever a file or folder is renamed, instead of editing import paths by hand, prevents forgotten references. Projects migrating to ESM should do it in one pass, converting every import to include its extension at once, rather than leaving a half-migrated codebase that throws scattered errors later.
Common mistakes
Deleting and reinstalling node_modules without first reading the file path in the error message wastes time when the real problem isn’t a missing package but a wrong path in your own code. Forgetting to add file extensions to relative imports is especially common in teams migrating away from CommonJS. Leaving TypeScript path aliases unconverted in a production build lets code run fine locally under ts-node and then break in production. And in monorepos, installing dependencies from the wrong package’s directory makes it unclear which node_modules is actually being used at runtime.
Checklist
First, determine whether the file path in the error is a package name or a relative path. If it’s a package name, confirm it’s listed in package.json and actually present inside node_modules. If it’s a relative path, check that it matches the real location of the file on disk. If your project uses ESM, make sure relative imports include their file extension. If you use TypeScript path aliases, confirm they get rewritten into real paths in the compiled output. If none of that resolves it, delete node_modules and the lock file and reinstall from scratch.
Next step
A “Cannot find module” error is usually just one broken link in the module resolution chain showing up in your terminal. Reading the message carefully resolves most of them within minutes. The key rule is understanding what the path actually points to before reaching for a fix. If you want your project’s dependency management, build process, or deployment architecture set up on solid foundations from the start, our group company Web Tasarım Ofisi provides end-to-end engineering consulting for software infrastructure and code management.
To set up your Node.js-based projects with a professional team, or to harden your existing infrastructure, explore our custom software service or get in touch with us. We cover other common roadblocks you may hit during setup in our guides to fixing an npm install error and fixing a port already in use error.
Sources
- Node.js Docs, Errors, ERR_MODULE_NOT_FOUND, Node.js’s official error reference defining module resolution errors and ESM-specific rules.
Frequently asked questions
Why does the "Cannot find module" error happen?
The most common causes are: the module was never installed (node_modules is missing it), a typo or case mismatch in the package name or file path, a missing file extension on a relative import under ECMAScript modules, and a TypeScript project whose tsconfig.json path aliases never get resolved in the compiled output. The file path printed right under the error message tells you directly which one you're dealing with.
Does deleting node_modules fix the "Cannot find module" error?
Often, yes, especially when a previous install was interrupted or the cache got corrupted. Deleting node_modules and package-lock.json and reinstalling with npm install rebuilds the dependency tree from scratch. But if the error points to a wrong file path or an invalid import statement, reinstalling won't help; you need to fix the code first.
Is the "Cannot find module" error the same for require and import?
No. Under CommonJS (require), Node.js can complete the file extension itself and throws the classic MODULE_NOT_FOUND error. Under ECMAScript modules (import, with "type": "module" in package.json), Node.js is stricter: it requires an explicit file extension on relative imports, and the error comes back with the ERR_MODULE_NOT_FOUND code. The two require different fixes, so figure out which module system your project uses first.
Why can't Node.js find a TypeScript path alias like @/utils after compiling?
The paths setting in tsconfig.json only tells the TypeScript compiler and your editor how to resolve the alias; it doesn't automatically rewrite that alias into a real relative path in the compiled JavaScript output. At runtime, Node.js has no idea what @/utils means, so it throws a Cannot find module error. The fix is adding a tool like tsc-alias or tsconfig-paths to rewrite the aliases into real paths during the build step.