Webpack 'Module not found' for local packages — real fix
Webpack can't find your local package because it looks in the wrong folder. The fix is telling Webpack where to search — usually the node_modules or a symlink.
You're working on a project, you npm install a local package from a sibling folder or a monorepo, and Webpack just gives you Module not found: Error: Can't resolve 'my-local-package'. It's annoying. Here's the fix, then I'll explain why it happens.
Quick fix
Open your webpack.config.js. Add this to the resolve object:
const path = require('path');
module.exports = {
// ... rest of config
resolve: {
modules: [
path.resolve(__dirname, 'node_modules'),
'node_modules'
],
symlinks: false
}
};
That's it. Restart your Webpack dev server. The error should be gone.
Why this works
What's actually happening here is: Webpack has a default list of folders where it looks for modules. By default, it goes up the directory tree looking for node_modules. When you install a local package using npm link or yarn link, the package lives outside your project's node_modules. The symlink points to a folder that Webpack can't resolve because it doesn't follow the symlink by default.
The modules array tells Webpack exactly where to look — first in your project's own node_modules, then in any parent folder. The symlinks: false is the key part. When Webpack sees a symlink, it follows it and resolves the real path. Without this flag, Webpack sometimes resolves the symlink's location incorrectly, and your local package's dependencies get confused.
The reason step 3 works is: symlinks: false makes Webpack treat the symlinked package as if it was actually inside your node_modules. It resolves the package's own dependencies relative to the original location, not the symlink target. This avoids the classic 'duplicate React' or 'wrong version of lodash' nightmare.
Less common variations
Monorepo with workspaces (Yarn / npm workspaces)
If you're using Yarn workspaces or npm workspaces, the issue is slightly different. The packages are hoisted to a root node_modules, but Webpack still looks in your project's local node_modules first. The fix here is to add the root node_modules path:
resolve: {
modules: [
path.resolve(__dirname, '../../node_modules'), // adjust path to your root
'node_modules'
]
}
But wait — if you have multiple workspace packages, this can break when they share the same dependency. A better approach: use resolve.alias to point directly to the local package's source folder:
resolve: {
alias: {
'my-local-package': path.resolve(__dirname, '../my-local-package/src/index.js')
}
}
This skips node_modules entirely and points straight to the source. It's faster and more predictable.
TypeScript + Webpack
If you're also using ts-loader or awesome-typescript-loader, the problem can be in TypeScript's own resolution. Add this to tsconfig.json:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"my-local-package": ["../my-local-package/src/index.ts"]
}
}
}
And make sure Webpack's resolve.modules matches the baseUrl. Usually it works out of the box if you use tsconfig-paths-webpack-plugin.
Docker or CI environments
In a Docker build, symlinks can break because the symlink target might not exist in the container. The fix: copy the local package directly into your project's node_modules during Docker build, or use a volume mount. Don't rely on npm link in Docker — it's unreliable. Instead, in your package.json, use a relative path dependency:
"dependencies": {
"my-local-package": "file:../my-local-package"
}
Then run npm install inside the container. Webpack will resolve it through the regular node_modules structure.
Prevention
Do this from the start:
- Set
symlinks: falsein your Webpack config if you use any symlinked packages. It's a one-liner that saves hours. - For monorepos, use
resolve.aliasinstead of relying on workspace hoisting — it's explicit and won't break when you restructure folders. - If you're using npm link for development, switch to
file:dependencies inpackage.jsonfor production builds. They don't require symlink support. - Test your build in CI before merging — local symlinks won't exist there.
One last thing: if you're on Windows, symlinks require admin rights or developer mode. If you can't enable it, skip npm link entirely and use file: dependencies or resolve.alias. The error will keep haunting you otherwise.
Was this solution helpful?