Node.js: Error: Cannot find module — causes and fixes

Node looked for the module in the places it searches — the project’s node_modules folder, then parent folders — and it wasn’t there under that name. Nearly every case is one of three things: the package was never installed in this project, the install is stale, or a path to your own file is slightly wrong (including letter case, which Linux and servers enforce even when your Mac doesn’t).

The fix, in order

  1. If it’s a package (no ./ or ../ in the name): run npm install in the project root. Then, if it’s still missing, install it by name: npm install packagename — this also records it in package.json so the next machine gets it too.
  2. If the project was copied or cloned, delete node_modules and reinstall cleanly: remove the folder and package-lock.json is NOT required — simply run npm install again; for an exact reproduction use npm ci.
  3. If it’s your own file (starts with ./ or ../): check the path from the file doing the require/import — not from the project root. Relative paths are resolved from the current file’s folder.
  4. Check the exact spelling and case of the file name, including the extension. require("./Utils") fails on Linux if the file is utils.js — and code that “works on my machine” fails on deploy for exactly this reason.
  5. Check package.json’s "main" and your start script if the missing module is the project itself (Cannot find module .../index.js): the entry file was renamed or moved.

If it still happens

Still stuck? Read the full error: Node prints a “Require stack” listing the chain of files that led to the failing line — the top entry is the file to fix. And confirm you’re running the project’s Node from its root folder; running a script from another directory changes what relative paths mean.

Common questions

I ran npm install and it still can’t find the module. Why? Check you ran it in the project root (where package.json lives), and that the package name in your code matches the installed name exactly — scoped packages (@scope/name) and near-miss spellings are common.

Why does it work locally but fail when deployed? Case sensitivity, most of the time. Windows and default macOS file systems forgive wrong case in file names; Linux servers don’t. Match the file name’s case exactly in the import.

Related errors

Python: ModuleNotFoundError · npm ERR! ERESOLVE · EADDRINUSE — port already in use