Storybook "build-storybook" Fails in CI - Fix the Static Build
The static Storybook build (storybook build) compiles every story and its builder (Vite or Webpack) the same way a production app build does. A broken story import, a misconfigured framework/builder, or an incompatible addon fails the build in CI even if storybook dev ran.
What this error means
The storybook build step fails - a builder error, a "Cannot find module" from a story, or an addon/framework version error. CI catches it because the static build compiles everything, unlike the on-demand dev server.
=> Failed to build the preview
ModuleNotFoundError: Module not found: Error: Can't resolve
'../components/Button' in '/app/src/stories'
at /app/node_modules/@storybook/builder-webpack5/...Diagnose it: is it resolution, transform, or memory?
Bundler failures in CI fall into three families and the error text often points at the wrong one. A module that resolves on your machine and not on the runner is nearly always case sensitivity or a missing optional dependency; a transform error is a config or version mismatch; and an unexplained kill with no stack is the out-of-memory reaper, not a build error at all.
# 1. resolution: does the file exist with EXACTLY that case?
git ls-files | grep -i "the/imported/path"
# 2. transform: what versions is CI actually resolving?
npm ls webpack vite rollup esbuild typescript 2>/dev/null | head -20
# 3. memory: was it killed rather than failed?
# exit 137 = SIGKILL (OOM). Nothing in the bundler log will explain it.
node --max-old-space-size=4096 node_modules/.bin/vite buildCommon causes
Broken story import or path
A story imports a component that moved, was renamed, or has a case-mismatched path. The dev server may not have compiled that story; the static build compiles all of them.
Addon or framework version mismatch
An addon or @storybook/* package on a different major than the core, or a stale builder, fails to load during the build.
Builder config or env missing in CI
A .storybook/main builder option, alias, or env var that exists locally is absent in CI, so the builder cannot resolve modules.
How to fix it
Fix story imports and align Storybook packages
Correct broken imports, then keep every @storybook/* package and addon on the same major.
npx storybook build # reproduce the static build locally
npx storybook doctor # flags version mismatches and bad addonsMirror builder config and env into CI
- Ensure
.storybook/mainaliases match your app's bundler resolution. - Provide any env vars the stories or builder read in the CI build step.
- Match import casing to filenames for the case-sensitive runner.
Make the build reproducible before you debug it
- Pin the Node major in
setup-nodeand inengines. A bundler that resolves native bindings will pick a different prebuilt binary across majors. - Delete
node_moduleslocally and reinstall from the lockfile before concluding the runner is at fault; most "works locally" reports are stale local state. - Set
CI=truelocally to reproduce. Several toolchains change behaviour under it, including treating warnings as errors. - Exit code 137 is an out-of-memory kill. Raise
--max-old-space-sizeor move to a larger runner rather than searching the bundler config.
How to prevent it
- Run
storybook buildin CI, not juststorybook dev. - Keep all
@storybook/*packages and addons on one major. - Mirror builder aliases and env vars from the app into
.storybook.