Web Components and Preact
Purpose and Scope
This page orients teams using Storybook with Vite-based non-React-DOM or React-adjacent targets: Web Components, Preact with Vite, and React Native Web with Vite. In all three cases, Storybook’s job is the same: run a browser-based workshop where components can be developed, tested, and documented in isolation. The renderer changes how stories mount a component, but the builder path is shared because these framework pages use Vite to bundle stories and preview code for the browser. Sources: docs/builders/vite.mdx
The practical takeaway is that a framework package such as Web Components Vite, Preact Vite, or React Native Web Vite selects the renderer integration, while the Vite builder handles bundling, dev startup, refresh behavior, and production static builds. Storybook’s Vite builder is documented as the default builder and recommended in most cases. It is especially natural for applications already built with Vite because Storybook can reuse the project’s existing Vite configuration instead of asking teams to maintain a separate bundler setup. Sources: docs/builders/vite.mdx
Relevant Source Files
- docs/builders/vite.mdx — Documents the Vite builder, setup flow, configuration merging,
viteFinal,viteConfigPath,configLoader, TypeScript configuration, and Webpack-to-Vite migration guidance that applies to these Vite framework integrations.
Framework Fit
Use Web Components Vite when your UI is authored as custom elements or standards-based Web Components and you want Storybook to render those components directly in the browser. The official framework docs describe this as Storybook for applications using Web Components built with Vite and list Vite as a requirement. In that setup, stories typically exercise attributes, properties, slots, events, and composed DOM behavior rather than React-style props, but the build and dev-server expectations still follow Storybook’s Vite builder model.
Use Preact Vite when the application uses Preact and Vite, and you want the Storybook renderer to understand Preact components while still preserving a Vite-native development loop. The official docs describe support for Preact applications built with Vite and identify Preact version compatibility alongside the Vite requirement. From a Storybook configuration perspective, this means the selected framework package provides the Preact renderer while Vite remains the builder that resolves modules, transforms source files, and powers browser refresh.
React Native Web Vite is slightly different conceptually because it targets React Native components rendered through React Native Web in a browser. The official docs position it as a way to develop and test React Native UI components in isolation using Vite for web browsers, while also noting that Storybook supports on-device React Native development separately. Choose this path when the browser preview is the right feedback loop for your React Native component library, especially when web-compatible stories, interaction tests, and documentation are part of the workflow.
Installation and First Run
For all three framework families, the high-level install command is intentionally consistent: run npm create storybook@latest from the root of an existing project. The installer detects the project and writes the Storybook configuration needed for that framework. In a Vite application, the builder documentation says that if Storybook was initialized in the Vite app, the builder is already installed and configured. That means most projects should not begin by hand-authoring builder configuration; start from the generated setup and only customize once a concrete requirement appears. Sources: docs/builders/vite.mdx
npm create storybook@latest
npm run storybookAfter installation, run the project’s Storybook script, commonly npm run storybook, to start the local development server. The framework determines how component stories render, while Vite supplies the fast ESM-based bundling path. This division is useful when debugging setup problems: if a component does not render correctly, inspect renderer-specific story code first; if aliases, transforms, static imports, or environment-dependent build behavior fail, inspect the Vite configuration path described below.
Configuration Model
Storybook’s Vite builder includes framework defaults and merges them with the project’s existing Vite configuration. The builder documentation recommends putting normal application build configuration in vite.config.js or vite.config.ts for the best experience, because Storybook automatically merges that configuration when it loads. This is the preferred model for Web Components, Preact, and React Native Web Vite projects: keep shared aliases, plugins, CSS behavior, and dependency settings in Vite, then let Storybook consume them through the selected framework integration. Sources: docs/builders/vite.mdx
When Storybook needs a configuration difference that should apply only inside Storybook, use the viteFinal function in .storybook/main.js or .storybook/main.ts. The documented contract is asynchronous: viteFinal receives the default builder configuration and returns the updated configuration. This is the right place to add Storybook-only aliases, conditionally include a plugin, or adapt configuration based on the environment. For TypeScript projects, the builder docs explicitly support renaming .storybook/main.js to .storybook/main.ts and configuring the builder with TypeScript. Sources: docs/builders/vite.mdx
// .storybook/main.ts
import type { StorybookConfig } from '@storybook/your-framework';
import { mergeConfig } from 'vite';
const config: StorybookConfig = {
framework: '@storybook/your-framework',
async viteFinal(config, context) {
return mergeConfig(config, {
resolve: {
alias: {
'@app': '/src',
},
},
});
},
};
export default config;Builder Options Reference
| Surface | Where it is configured | What it is for |
|---|---|---|
framework | `.storybook/main.js | ts` |
viteFinal(config, context) | `.storybook/main.js | ts` |
viteConfigPath | framework builder options | Points Storybook at a Vite config file outside the default root lookup location. |
configLoader | builder options | Passes Vite’s config loader mode through to Vite, equivalent to the Vite --configLoader command-line argument. |
The Vite builder normally searches for the Vite configuration file in the root directory of the Storybook project. If your repository keeps Vite configuration somewhere else, set viteConfigPath in the framework builder options. The documentation also notes a useful edge case: pointing viteConfigPath at a non-existent file prevents Storybook from automatically loading a Vite config. That can help isolate whether a startup problem comes from application Vite configuration or Storybook’s framework defaults. Sources: docs/builders/vite.mdx
Migration and Troubleshooting
If a project is moving from Webpack or Create React App conventions into a Vite-based Storybook, avoid copying every old loader and plugin into viteFinal. The Vite builder guidance says Vite handles many cases out of the box, including common style loading, and recommends starting with no Storybook-specific Vite configuration. Add only the customizations the project proves it needs. That advice applies strongly to Web Components and Preact projects, where unnecessary compatibility config can hide simpler Vite-native solutions. Sources: docs/builders/vite.mdx
For React Native Web Vite, migration troubleshooting often means separating platform adaptation from builder configuration. A component may require React Native Web aliases or package-level compatibility settings, while the Storybook builder still follows the same Vite merge and override rules. Work from the generated configuration, confirm that the selected framework matches the intended renderer, then use viteFinal, viteConfigPath, or environment-based Vite config only for differences that are truly Storybook-specific. Next, read the Vite Builder page for deeper builder behavior and the Writing Stories pages for framework-neutral story authoring patterns.