How to Configure Storybook with Webpack 5 and Vite Builders: A Complete Guide

Configure Storybook with Webpack 5 or Vite by setting the core.builder property in .storybook/main.js to @storybook/builder-webpack5 or @storybook/builder-vite, then install the corresponding framework package such as @storybook/react or @storybook/react-vite.

Storybook's architecture separates the UI framework from the bundling logic through a system called builders. Whether you are working with a legacy Webpack codebase or a modern Vite-powered project, you can configure Storybook with webpack and vite builders to match your existing toolchain. This guide references the actual implementation in the storybookjs/storybook repository to show you exactly how the builder selection works and how to customize each option.

Understanding Storybook Builders

Builders are pluggable modules that generate the preview bundle and serve it during development. Storybook officially supports two builders:

  • Webpack 5 (@storybook/builder-webpack5): Ideal for projects already relying on Webpack, such as Create React App, Next.js, or custom Webpack configurations.
  • Vite (@storybook/builder-vite): Optimized for fast, native-ESM projects using Vite's dev server and Rollup-based bundling, perfect for Vite-powered React, Vue 3, or Svelte applications.

The builder works in tandem with the framework package (e.g., @storybook/react or @storybook/react-vite). While the framework provides type definitions and preset plugins, the builder actually creates the bundle. Internally, the core server detects your builder choice in code/core/src/core-server/build-dev.ts and launches the appropriate dev server.

Configure Storybook with the Webpack 5 Builder

Installation

Install the Webpack 5 builder alongside your framework package:

npm i -D @storybook/react @storybook/builder-webpack5

Replace @storybook/react with your specific framework package (e.g., @storybook/vue3, @storybook/angular) if needed.

Main Configuration

Create or update .storybook/main.js to specify the Webpack 5 builder in the core section:

// .storybook/main.js (Webpack 5)
// Source: https://github.com/storybookjs/storybook/blob/next/docs/_snippets/storybook-main-webpack5.md
export default {
  framework: '@storybook/react',
  stories: ['../src/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  
  core: {
    builder: '@storybook/builder-webpack5',
  },
};

Customizing Webpack

To modify the Webpack configuration, use the webpackFinal function in your main configuration:

export default {
  // ... other config
  webpackFinal: async (config) => {
    // Add custom loaders or modify resolve.alias
    config.module.rules.push({
      test: /\.custom$/,
      use: 'custom-loader',
    });
    return config;
  },
};

The Webpack 5 builder preset is defined in code/builders/builder-webpack5/preset.ts, which exposes the plugins that Storybook injects into the build pipeline.

Configure Storybook with the Vite Builder

Installation

Install the Vite builder and the corresponding Vite-enabled framework package:

npm i -D @storybook/react-vite @storybook/builder-vite

Available framework packages include @storybook/react-vite, @storybook/vue3-vite, @storybook/svelte-vite, and others.

Main Configuration

Update .storybook/main.js to enable the Vite builder:

// .storybook/main.js (Vite)
// Source: https://github.com/storybookjs/storybook/blob/next/docs/_snippets/storybook-vite-builder-register.md
export default {
  framework: '@storybook/react-vite',
  stories: ['../src/**/*.mdx', '../stories/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  
  core: {
    builder: '@storybook/builder-vite',
  },
};

Customizing Vite

Modify the Vite configuration using the viteFinal function:

export default {
  // ... other config
  viteFinal: async (config) => {
    // Add plugins or modify resolve.alias
    config.plugins.push(myCustomPlugin());
    return config;
  },
};

The Vite builder uses virtual files for Storybook-specific entry points, defined in code/builders/builder-vite/src/virtual-file-names.ts, such as virtual:/@storybook/builder-vite/vite-app.js. The builder preset in code/builders/builder-vite/preset.ts exposes the Vite plugins that Storybook injects into the build pipeline.

Switching Between Builders

You can switch between Webpack 5 and Vite by changing a single configuration value and reinstalling dependencies. No story files or component code require modification.

To switch from Webpack 5 to Vite:

  1. Change the builder value:

    core: { builder: '@storybook/builder-vite' }
  2. Install the Vite framework package (e.g., @storybook/react-vite) and remove the Webpack framework package if no longer needed.

To switch back to Webpack 5, reverse the process:

core: { builder: '@storybook/builder-webpack5' }

How Storybook Detects and Loads Builders

When you run storybook dev, the core server in code/core/src/core-server/build-dev.ts detects your builder choice by checking the resolvedPreviewBuilder value. If the string contains 'builder-vite', Storybook launches the Vite dev server; otherwise, it initializes the Webpack 5 compiler.

The builder preset (located at code/builders/builder-webpack5/preset.ts or code/builders/builder-vite/preset.ts) exposes the specific plugins that Storybook injects into the bundler pipeline. Framework-specific presets (such as code/frameworks/react-vite/src/preset.ts or code/frameworks/react-webpack5/src/preset.ts) then add additional plugins for JSX handling, CSS processing, and other framework-specific concerns.

Telemetry data collected in code/core/src/telemetry/* records which builder is active using the SupportedBuilder.VITE or SupportedBuilder.WEBPACK5 enums, helping the maintainers track usage patterns across the ecosystem.

Summary

  • Builders are pluggable modules that generate the Storybook preview bundle, with official support for Webpack 5 (@storybook/builder-webpack5) and Vite (@storybook/builder-vite).
  • To configure Storybook with webpack and vite builders, set the core.builder property in .storybook/main.js and install the matching framework package (e.g., @storybook/react for Webpack or @storybook/react-vite for Vite).
  • Customize the underlying bundler using webpackFinal for Webpack 5 or viteFinal for Vite to add loaders, plugins, or modify resolve aliases.
  • The core server detects the active builder in code/core/src/core-server/build-dev.ts and loads the appropriate preset from code/builders/builder-webpack5/preset.ts or code/builders/builder-vite/preset.ts.

Frequently Asked Questions

Can I use both Webpack and Vite builders in the same project?

No, a single Storybook instance can only use one builder at a time. However, you can maintain separate configuration files (e.g., .storybook/main.webpack.js and .storybook/main.vite.js) and launch Storybook with the --config-dir flag to switch between them for testing purposes. Each builder requires its own framework package and dependency set.

How do I migrate from Webpack 5 to Vite in Storybook?

Migration involves three steps: first, install the Vite builder and corresponding framework package (e.g., npm i -D @storybook/builder-vite @storybook/react-vite); second, update .storybook/main.js to change the framework value to the Vite variant and set core.builder to @storybook/builder-vite; third, migrate any custom webpackFinal logic to viteFinal since Vite uses Rollup for production builds. No changes to your .stories files are required.

Where does Storybook store builder-specific virtual files?

The Vite builder uses virtual file names defined in code/builders/builder-vite/src/virtual-file-names.ts to provide Storybook-specific entry points such as virtual:/@storybook/builder-vite/vite-app.js. These virtual modules allow the builder to inject runtime code without writing physical files to disk. The Webpack 5 builder handles similar concerns through its preset configuration in code/builders/builder-webpack5/preset.ts.

Does changing the builder affect my existing stories?

No, changing the builder does not require any modifications to your existing story files or component code. The builder only affects how the preview bundle is generated and served. As long as your stories use standard component syntax supported by your framework, they will work identically under both Webpack 5 and Vite. You may need to adjust custom webpack or vite configurations if you rely on specific loaders or plugins.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →