> **Version 8** — **React** / **TypeScript**
> Also available:
- `?language=js` for JavaScript
- `?codeOnly=true` for code snippets only
- other versions: Version 10.3 (latest) (`/docs/configure/webpack.md`), Version 9 (`/docs/9/configure/webpack.md`)

# Webpack

Storybook displays your components in a custom web application built using [Webpack](https://webpack.js.org/). Webpack is a complex tool, but our default configuration is intended to cover most use cases. [Addons](https://storybook.js.org/addons/) are also available that extend the configuration for other everyday use cases.

You can customize Storybook's webpack setup by providing a `webpackFinal` field in [`.storybook/main.js`](./index.mdx#configure-your-storybook-project) file.

The value should be an async function that receives a webpack config and eventually returns a webpack config.

### Default configuration

By default, Storybook's webpack configuration will allow you to:

#### Import images and other static files

You can import images and other local files and have them built into the Storybook:

```js
// MyComponent.stories.js|jsx|mjs|ts|tsx
// This will include './static/image.png' in the bundle.
// And return a path to be included in a src attribute

```

#### Import JSON as JavaScript

You can import `.json` files and have them expanded to a JavaScript object:

```js
// MyComponent.stories.js|jsx|mjs|ts|tsx
// This will automatically be parsed to the contents of `data.json`

```

If you want to know the exact details of the webpack config, the best way is to run either of the following:

```shell

## Development mode
yarn storybook dev --debug-webpack

## Production mode
yarn storybook build --debug-webpack
```

When you start your Storybook, you'll see an improvement in loading times. Read more about it in the [announcement post](https://storybook.js.org/blog/storybook-on-demand-architecture/) and the [configuration documentation](./index.mdx#on-demand-story-loading).

### Webpack 5

Storybook builds your project with Webpack 4 by default. If your project uses Webpack 5, you can opt into the Webpack 5 builder by installing the required dependencies (i.e., `@storybook/builder-webpack5`, `@storybook/manager-webpack5`) and update your Storybook configuration as follows:

```js
// .storybook/main.js
export default {
  core: {
    builder: '@storybook/builder-webpack5',
  },
};
```

Once you are using Webpack 5, you can further opt into some features to optimize your build:

#### Lazy Compilation

Storybook supports Webpack's experimental [lazy compilation](https://webpack.js.org/configuration/experiments/#experimentslazycompilation) feature, via the `lazyCompilation` builder flag:

```js
// .storybook/main.js
export default {
  core: {
    builder: {
      name: 'webpack5',
      options: {
        lazyCompilation: true,
      },
    },
  },
};
```

This feature applies in development mode, and will mean your Storybook will start up faster, at the cost of slightly slower browsing time when you change stories.

#### Filesystem Caching

Storybook supports Webpack's [filesystem caching](https://webpack.js.org/configuration/cache/#cachetype) feature, via the `fsCache` builder flag:

```js
// .storybook/main.js
export default {
  core: {
    builder: {
      name: 'webpack5',
      options: {
        fsCache: true,
      },
    },
  },
};
```

This feature will mean build output is cached between runs of Storybook, speeding up subsequent startup times.

### Extending Storybook’s webpack config

To extend the above configuration, use the `webpackFinal` field of [`.storybook/main.js`](./index.mdx#configure-story-rendering).

The value should export a `function`, which will receive the default config as its first argument. The second argument is an options object from Storybook, and this will have information about where config came from, whether we're in production or development mode, etc.

For example, if you need to adjust the config for a specific environment, you can do so like this:

```ts
// .storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)

const config: StorybookConfig = {
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  webpackFinal: async (config, { configType }) => {
    if (configType === 'DEVELOPMENT') {
      // Modify config for development
    }
    if (configType === 'PRODUCTION') {
      // Modify config for production
    }
    return config;
  },
};

export default config;
```

Storybook uses the config returned from the above function to render your components in Storybook's "preview" iframe. Note that Storybook has an entirely separate webpack config for its UI (also referred to as the "manager"), so the customizations you make only apply to the rendering of your stories, i.e., you can completely replace `config.module.rules` if you want.

Nevertheless, edit `config` with care. Make sure to preserve the following config options:

* **entry**
* **output**

Furthermore, `config` requires the `HtmlWebpackplugin` to generate the preview page, so rather than overwriting `config.plugins` you should probably append to it (or overwrite it with care), see [the following issue](https://github.com/storybookjs/storybook/issues/6020) for examples on how to handle this:

```ts
// .storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)

const config: StorybookConfig = {
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  webpackFinal: async (config) => {
    config.plugins.push(/* ... */);
    return config;
  },
};

export default config;
```

Finally, if your custom webpack config uses a loader that does not explicitly include specific file extensions via the `test` property, in that case, it is necessary to `exclude` the `.ejs` file extension from that loader.

If you're using a non-standard Storybook config directory, you should put `main.js` there instead of `.storybook` and update the `include` path to ensure it resolves to your project root.

### Using your existing config

Suppose you have an existing webpack config for your project and want to reuse this app's configuration. In that case, you can import your main webpack config into Storybook's [`.storybook/main.js`](./index.mdx#configure-story-rendering) and merge both:

The following code snippet shows how you can replace the loaders from Storybook with the ones from your app's `webpack.config.js`:

```ts
// .storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)

const config: StorybookConfig = {
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  webpackFinal: async (config) => {
    return {
      ...config,
      module: { ...config.module, rules: [...config.module.rules, ...custom.module.rules] },
    };
  },
};

export default config;
```

  Projects initialized via generators (e.g, Vue CLI) may require that you import their own webpack config file (i.e., <code>/projectRoot/node\_modules/@vue/cli-service/webpack.config.js</code>) to use a certain feature with Storybook. For other generators, make sure to check the documentation for instructions.

### TypeScript Module Resolution

When working with TypeScript projects, the default Webpack configuration may fail to resolve module aliases defined in your [`tsconfig` file](https://www.typescriptlang.org/tsconfig). To work around this issue you may use [`tsconfig-paths-webpack-plugin`](https://github.com/dividab/tsconfig-paths-webpack-plugin#tsconfig-paths-webpack-plugin) while [extending Storybook's Webpack config](#extending-storybooks-webpack-config) like:

```ts
// .storybook/main.ts
// Replace your-framework with the framework you are using (e.g., react-webpack5, vue3-vite)

const config: StorybookConfig = {
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  webpackFinal: async (config) => {
    if (config.resolve) {
      config.resolve.plugins = [
        ...(config.resolve.plugins || []),
        new TsconfigPathsPlugin({
          extensions: config.resolve.extensions,
        }),
      ];
    }
    return config;
  },
};

export default config;
```

  Learn more about Storybook's <a href="./typescript">built-in TypeScript support</a> or see <a href="https://github.com/storybookjs/storybook/issues/14087">this issue</a> for more information.