Module not found: Can't resolve

Next.js monorepo: fix 'Module not found: Can't resolve'

Next.js can't find a package in your monorepo. Here's why it happens and how to fix it fast, without tearing your hair out.

You're working in a monorepo, you've got a shared package that your Next.js app imports, and suddenly you see this in the terminal:

Module not found: Can't resolve 'my-shared-package'

This usually pops up right after you've added a new package to your workspace, or when you're running next dev and it tries to compile a component that imports that package. Maybe you're using pnpm, yarn workspaces, or npm workspaces—doesn't matter. The error is the same, and the cause is almost always the same.

Why does this happen?

Next.js uses webpack under the hood, and webpack resolves modules by looking in node_modules and, by default, only in the app's own directory. When you have a monorepo, your shared packages live outside the Next.js app's folder—often in a packages/ directory at the root. Webpack doesn't automatically look up the directory tree for packages in a workspace.

So even though the package is installed (you can see it in node_modules at the root), Next.js can't find it because it's not in the app's node_modules, and webpack's default resolution doesn't go looking for it.

I've seen this trip up a lot of devs, especially when they switch from a simple single-repo setup to a monorepo. Last month, a client of mine had a shared UI library that kept throwing this error whenever they tried to import a button component. The package was right there, but Next.js just couldn't see it.

The fix: tell Next.js where to look

You've got two solid ways to fix this. I'll give you the one that works 95% of the time first, then the fallback.

Option 1: Use transpilePackages (the clean fix)

Next.js has a built-in option called transpilePackages that tells webpack to compile packages from your monorepo directly. Add it to your next.config.js:

// next.config.js
module.exports = {
  transpilePackages: ['my-shared-package'],
}

If you have multiple shared packages, list them all:

transpilePackages: ['@mycompany/ui', '@mycompany/utils'],

This works because it forces webpack to look for those packages in the workspace root and compile them as part of your app's build. It's the official way to handle monorepos in Next.js 13+.

Option 2: Configure webpack aliases (the manual fix)

If transpilePackages isn't enough—maybe your package has some edge-case exports—you can set up a webpack alias to point directly to the source:

// next.config.js
const path = require('path');

module.exports = {
  webpack: (config) => {
    config.resolve.alias['my-shared-package'] = path.resolve(__dirname, '../packages/my-shared-package');
    return config;
  },
};

This is more brute-force, but it works. I've used this when a package had a weird build setup that transpilePackages didn't catch.

Step-by-step: Getting it working

  1. First, confirm the package is actually installed. Run npm ls my-shared-package (or yarn why or pnpm why) from the root. If it's not listed, install it: npm install -w my-app my-shared-package.
  2. Open your next.config.js. Add the transpilePackages array with the package name (exactly as you import it, including the scope if it has one).
  3. Restart your dev server. Kill it completely (Ctrl+C) and run next dev again. This is important—Next.js sometimes caches the old config.
  4. Clear the .next folder if the error persists: rm -rf .next then restart.
  5. If it still fails, try the webpack alias approach.

What else could be wrong?

If you've done all that and the error won't go away, check these:

  • Is the package's main field correct? Open its package.json. If main points to a file that doesn't exist or a build folder you haven't built yet, webpack will fail. If it's a TypeScript package, you might need to point to the source (src/index.ts) or build it first.
  • Are you using pnpm? pnpm's strict node_modules structure can cause extra pain. Add this to your app's .npmrc or root .npmrc: node-linker=hoisted and see if that helps. Or you can use public-hoist-pattern[]=* to hoist everything.
  • Is the package listed in the app's dependencies? Even in a monorepo, your app needs to declare the dependency in its own package.json. If it's only in the root, Next.js might not see it. Add it explicitly.
  • Did you check the import path? Sounds dumb, but I've spent an hour on this before and it was a typo. Make sure the import matches the package name in its package.json.

That last one—the typo—happens more than you'd think. And the pnpm one is a real gotcha. I moved a project from npm to pnpm once and had to add node-linker=hoisted to fix a dozen of these errors.

The real fix is usually transpilePackages. It's the modern way, it's documented, and it handles most monorepo setups. If you're on an older Next.js version (before 13), you'll need the webpack alias, because transpilePackages didn't exist then.

Once you've got it working, you won't see this error again—until you add another package. But now you know the drill: add it to transpilePackages, restart, and move on with your life.

Related Errors in Programming & Dev Tools
0X40010001 DBG_REPLY_LATER (0X40010001): Debugger blocking issue fixed ModuleNotFoundError: No module named 'pip' Fix pip Missing After Python Upgrade on Windows and macOS 0X00010002 0X00010002 Debugger Continued – Why It Happens and the Real Fix 0XC0000270 Fix STATUS_WX86_FLOAT_STACK_CHECK 0xC0000270 on Windows

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.