Module not found: Failed to resolve import

Filed under Next.js & React errors

The fix, fast

Read the exact path named in the error and check it letter by letter: most cases are a typo, a capitalisation mismatch, a package that was never installed, or a file that moved. Verify the package is listed in package.json and reinstall if it is missing, and if you use the @/ shortcut, make sure it is configured in both tsconfig.json and vite.config.ts — then restart the dev server.

Why this happens

An import is your code asking for another file or an installed package by name — for example import Button from "./components/Button". “Module not found” or “Failed to resolve import” means the tool building your app, Vite or Next.js, followed that address and found nothing at the end of it.

The sneaky part is that the address can look right to you and still be wrong to the computer. File systems on Linux — which is what most deployment services and many dev servers run on — are case-sensitive: Button.tsx and button.tsx are two different files there, even though your Mac or Windows machine may happily open either one. That is why code can work on your laptop and fail the moment you deploy it.

The other common causes are just as ordinary:

The fix, step by step

  1. Read the exact path in the error. Do not skim it. The error names the importer (the file doing the asking) and the path it could not resolve. Copy that path exactly — the fix is almost always visible in it once you compare it against reality:
    Failed to resolve import "./components/Buton" from "src/App.tsx".
    Does the file exist?
  2. Verify the package is actually installed, if it is a package. If the import has no ./ or @/ at the start, it is a package name. Check that it appears in package.json under dependencies, and reinstall everything cleanly if you are unsure:
    npm install
    # Or, if package.json lists it but it still fails:
    npm install the-package-name
    Replace the example name with the real package from your error.
  3. Check the spelling and capitalisation letter by letter. Compare the import against the actual file name on disk, character for character — including capitals in the middle of words and the file extension. Fix whichever side is wrong, preferably the import, and be consistent everywhere that file is imported.
  4. Check the relative path after any file moves. Count the folders: ./ means “this same folder,” each ../ climbs one folder up. Open the importing file, walk the path by hand in your file explorer, and confirm you land on the real file. If you cannot, update the import to the file’s new location.
  5. If you use @/, verify the alias in both places. TypeScript reads its map from tsconfig.json, while Vite reads its own config — one does not cover the other. Both should point @ to the same folder:
    // tsconfig.json
    {
      "compilerOptions": {
        "baseUrl": ".",
        "paths": { "@/*": ["./src/*"] }
      }
    }
    // vite.config.ts
    import path from "path";
    
    export default {
      resolve: {
        alias: { "@": path.resolve(__dirname, "./src") }
      }
    };
    In a Next.js project there is no vite.config.ts — Next.js follows the tsconfig.json paths — so a mismatch there usually means the tsconfig entry itself is missing or points at the wrong folder.
  6. Restart the dev server. Config files like vite.config.ts and tsconfig.json are read when the server starts, not continuously. Stop it completely and start it again after any config change; a browser refresh alone will keep showing the old error.

Give your AI this prompt

I am getting this module resolution error in my [Vite / Next.js — delete one] project:
[paste the full error here, including the importer file and the exact import path]

Work through it in this order and show me what you find at each step:
1. Read the exact path in the error and compare it, letter by letter including capitals, with the real file or package name.
2. If it is a package, check package.json — is it listed? If not, tell me the install command instead of guessing an alternative package.
3. If it is a relative path, walk it from the importing file and tell me where it actually lands versus where the file really is.
4. If the path starts with @/, check the alias in BOTH tsconfig.json paths and (for Vite) vite.config.ts resolve.alias, and confirm they point to the same folder.
5. Make ONE fix only — the smallest change that resolves this import. Do not rename or move other files, do not rewrite unrelated imports, and do not change my project structure.
6. Finish by reminding me to restart the dev server, and tell me what a successful start looks like.

One fix, every Friday.

One real error, explained in plain English, with the fix — in your inbox every Friday. No spam, no jargon, unsubscribe anytime.