Webpack Builder
Purpose and Scope
The Webpack builder is the Storybook builder path for projects that want Storybook to compile stories, component code, styling, assets, and documentation-related modules through Webpack. In Storybook terms, a builder is the part of the system that prepares browser-ready bundles for the preview experience and supports both development and static production output. The Webpack page describes this builder as Storybook’s historical builder and frames it as a way to develop UI components in isolation while reusing an existing Webpack setup when a project already has one.
Sources: docs/builders/webpack.mdx, docs/configure/webpack.mdx
This page is for developers deciding how to select Webpack 5, how to extend Storybook’s generated Webpack configuration, and how to avoid breaking the preview iframe while customizing it. Storybook provides a baseline Webpack configuration for common cases, so many projects do not need any custom setup at first. When the defaults are not enough, the supported extension point is the project’s Storybook main configuration file, where builder options and the webpack finalization hook can be defined without replacing the entire Storybook runtime.
Sources: docs/builders/webpack.mdx, docs/configure/webpack.mdx
Relevant Source Files
- docs/builders/webpack.mdx - Primary Webpack builder documentation, including builder purpose, supported builder options, configuration override guidance, plugin handling, importing existing Webpack configuration, and debugging direction.
- docs/configure/webpack.mdx - Configuration-oriented Webpack documentation that explains default Webpack behavior, static asset and JSON imports, Webpack 5 opt-in examples, lazy compilation, filesystem caching, and how custom configuration affects the preview iframe.
Selecting the Webpack Builder
Storybook’s builder selection is configured from the project’s main Storybook configuration. The Webpack builder documentation shows the builder being configured through the core builder field and exposes Webpack-specific options beneath that builder configuration. In current Storybook documentation, initialization usually detects the application’s environment and chooses a builder automatically, but explicit configuration is still important when a repository needs to opt into Webpack 5 behavior, preserve a Webpack-based pipeline, or compare builder behavior during a migration from another setup.
Sources: docs/builders/webpack.mdx, docs/configure/webpack.mdx
A minimal explicit builder selection uses the Storybook main configuration file. The exact framework package depends on the application, but the builder choice is represented through the core builder setting and, when needed, an options object. The builder README in the broader repository describes the Webpack 5 builder as the implementation used by Storybook core server to build the preview iframe, while the requested docs explain the user-facing configuration surface. For application maintainers, the practical takeaway is that builder selection belongs in configuration, not in individual stories.
Sources: docs/builders/webpack.mdx, docs/configure/webpack.mdx
// .storybook/main.js
export default {
core: {
builder: {
name: '@storybook/builder-webpack5',
options: {
lazyCompilation: true,
fsCache: true,
},
},
},
};Configuration Surface
Storybook’s Webpack defaults are intended to cover common development needs before custom Webpack work begins. The configuration documentation states that the default setup supports importing images and other local static files into stories and importing JSON files as JavaScript objects. Those defaults matter because story files often reference the same assets as production components. The builder page also emphasizes zero-config support: Storybook starts from a baseline configuration and then lets a project extend that baseline when performance, compatibility, or framework-specific requirements demand it.
Sources: docs/builders/webpack.mdx, docs/configure/webpack.mdx
The compact reference for the Webpack builder is small but important. The builder option lazy compilation enables Webpack’s experimental lazy compilation behavior for development mode, trading faster Storybook startup for slightly slower loading when a story is first browsed. The filesystem cache option enables Webpack filesystem caching so build output can be reused between runs. Both options are configured through the builder options object rather than through a story file, because they affect the build pipeline for the whole Storybook preview environment.
Sources: docs/builders/webpack.mdx, docs/configure/webpack.mdx
| Configuration item | Where it is set | What it controls |
|---|---|---|
| core.builder | .storybook/main.js or .storybook/main.ts | Selects the Webpack builder implementation. |
| core.builder.options.lazyCompilation | Builder options | Enables Webpack lazy compilation in development mode. |
| core.builder.options.fsCache | Builder options | Enables Webpack filesystem caching between runs. |
| webpackFinal(config, options) | .storybook/main.js or .storybook/main.ts | Receives the baseline Webpack config and returns the final preview config. |
| --debug-webpack | Storybook CLI | Prints the Webpack configuration used for development or production builds. |
Extending the Preview Webpack Configuration
For customization, Storybook exposes webpackFinal in the main configuration file. The hook receives the baseline Webpack configuration as its first argument and a Storybook options object as its second argument, then returns the configuration that Storybook will use. This is the right place to add a loader, append a plugin, merge an existing project Webpack file, or apply environment-specific build changes. The docs are explicit that once webpackFinal is used, the project is responsible for merging carefully rather than assuming Storybook can infer every intended change.
Sources: docs/builders/webpack.mdx, docs/configure/webpack.mdx
The preview iframe is the key boundary to understand. Storybook uses the configuration returned from webpackFinal to render stories inside the preview iframe, while the Storybook manager UI has a separate build path. That means preview customizations affect component rendering, story modules, loaders for application code, and assets used by stories. They do not directly customize the manager UI shell. This separation is useful because a project can adjust story rendering deeply without taking ownership of the entire Storybook interface build.
Sources: docs/builders/webpack.mdx, docs/configure/webpack.mdx
// .storybook/main.js
export default {
async webpackFinal(config, options) {
config.module.rules.push({
test: /\.example$/u,
use: ['raw-loader'],
});
return config;
},
};Implementation Details and Edge Cases
The most important safety rule is to preserve the entry and output properties when changing the Webpack configuration. Storybook relies on those fields to assemble and serve the preview application correctly. The builder documentation also calls out HtmlWebpackPlugin because Storybook depends on it to generate the preview page. If a project replaces the plugins array outright, it can accidentally remove the plugin Storybook needs. The safer pattern is to append plugins or loaders to the existing arrays, then return the modified configuration.
Sources: docs/builders/webpack.mdx, docs/configure/webpack.mdx
Loader rules require similar care. The Webpack builder documentation warns that loaders without explicit file-extension matching should exclude the .ejs extension. That detail is easy to miss because broad loader rules often work in application builds, but Storybook’s preview page generation can involve template files that should not be processed by an unrelated application loader. When importing an existing Webpack configuration, merge it intentionally into Storybook’s default configuration instead of replacing everything, especially in projects scaffolded by generators with their own Webpack conventions.
Sources: docs/builders/webpack.mdx, docs/configure/webpack.mdx
Debugging and Next Steps
When the effective Webpack configuration is unclear, use the debug flag from the Storybook CLI in both development and production modes. The configuration docs show separate commands for development and build output, which helps distinguish startup-time behavior from optimized static output. Debugging is especially helpful after adding webpackFinal, importing an external Webpack file, enabling caching, or changing loader rules. If a story renders differently inside Storybook than in the application, inspect the final preview configuration before changing story code.
Sources: docs/builders/webpack.mdx, docs/configure/webpack.mdx
yarn storybook dev --debug-webpack
yarn storybook build --debug-webpackNext, read the Vite Builder page if you are comparing builder choices, Configure Overview for the main configuration file structure, and Story Rendering and Layout for preview behavior that is not specifically a Webpack concern. If your task is addon or framework authoring rather than application configuration, follow the framework and builder API material to understand the lower-level builder contract. For most application teams, start with the defaults, add only the builder options you can justify, and keep webpackFinal small and reviewable.