Diagnosing Module Resolution Errors in Storybook
A diagnostic guide to fixing 'Module not found' and resolution errors in Storybook, covering path aliases, case-sensitivity in CI, and provider configuration.
22 Aug 2025, 06:32 UTC

The Problem: 'Module Not Found' During Storybook Build
A common failure in Storybook environments is the Module not found or Cannot find module error. This typically occurs when the Storybook builder (Webpack or Vite) cannot map the import statement in a .stories.tsx or .stories.jsx file to a physical file on the disk. This often manifests as a white screen in the browser or a terminal crash during the build process.
Quick Diagnostic Table
| Symptom | Likely Cause | Primary Check |
|---|---|---|
| Works locally, fails in CI/CD | Case-sensitivity mismatch | Compare import case vs. filename |
| Error after moving a component | Broken relative path | Verify ../ depth in stories file |
Error using @components/ aliases |
Missing builder alias config | Check .storybook/main.js |
| Component loads but crashes on render | Missing Context Provider | Check .storybook/preview.js |
Step-by-Step Resolution Path
1. Validate Story Discovery Patterns
Before checking individual imports, ensure Storybook is actually looking in the right directories. If the story file itself isn't found, the builder may throw generic resolution errors.
Open .storybook/main.js (or .ts) and inspect the stories array. Ensure the glob pattern covers your component directory.
// .storybook/main.js
module.exports = {
stories: [
"../src/**/*.stories.@(js|jsx|ts|tsx)", // Ensure this matches your folder structure
],
// ... other config
};
2. Verify Case Sensitivity (CI/CD Failures)
Windows and macOS are often case-insensitive, but Linux (used in most CI runners) is case-sensitive. An import for ./Button.tsx will fail if the file is named button.tsx on a Linux agent.
- Check: Run
ls src/componentsin your terminal and compare the exact casing to theimportstatement in your story file. - Fix: Rename the file or the import to match exactly.
3. Configure Path Aliases
If you use absolute paths or aliases (e.g., import { Button } from '@components/Button'), Storybook's internal builder needs to be told how to resolve these, as it does not automatically inherit your tsconfig.json or jsconfig.json paths.
For Webpack-based Storybook, add a webpack final config in .storybook/main.js:
// .storybook/main.js
const path = require('path');
module.exports = {
// ... other config
webpackFinal: async (config) => {
config.resolve.alias = {
...config.resolve.alias,
'@components': path.resolve(__dirname, '../src/components'),
};
return config;
},
};
Risk: Modifying main.js requires a full restart of the Storybook server to take effect.
4. Resolve Runtime Context Crashes
If the module is found but the component fails to render with an error like Cannot read property 'X' of undefined, the component likely depends on a Provider (Redux, ThemeProvider, etc.) that exists in your main app but not in Storybook.
Add the necessary wrapper to .storybook/preview.js using a decorator:
// .storybook/preview.js
import { ThemeProvider } from '../src/context/ThemeContext';
export const decorators = [
(Story) => (
<ThemeProvider>
<Story />
</ThemeProvider>
),
];
Verification and Rollback
To verify the fix, run the Storybook build command from your project root:
npm run storybook
Check the terminal for Compiled successfully. If the error persists, check the browser console for the specific file path that is failing to load.
Rollback: If a webpackFinal change causes the build to hang or fail, revert the .storybook/main.js file to its previous state and restart the process.
Escalation Criteria
If the following conditions are met, the issue may be a version mismatch rather than a configuration error:
- The error occurs in
node_modulesrather than your source code. - The error persists after deleting
node_modulesand runningnpm install. - The error only appears after updating
@storybook/reactor@storybook/vuewithout updating the corresponding addons.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.