Vue and Svelte

Purpose and Scope

This page explains how Vue 3, Svelte, and SvelteKit projects fit into Storybook’s Vite-based framework model. The reader problem is practical: after choosing a renderer, you need to know which setup path to use, what Storybook expects from the host application, and where builder configuration belongs. In Storybook terminology, the renderer is the integration that knows how to mount components for a UI technology, while the builder is the bundling layer that compiles stories and the preview iframe. For these frameworks, the important shared builder is Vite, which Storybook describes as the default and recommended builder for most cases. Sources: docs/builders/vite.mdx

Vue 3 with Vite, Svelte with Vite, and SvelteKit all use the same first installation motion in an existing application: run Storybook’s create command from the project root, then start the local Storybook development server. The official framework docs describe these integrations as ways to develop and test UI components in isolation, with requirements of Vue 3 plus Vite 5 for Vue, Svelte 5 plus Vite 5 for Svelte, and SvelteKit 1.0 plus Vite 5 for SvelteKit. That means the framework decision is not only about syntax; it also chooses the renderer package that interprets stories, args, decorators, and docs for the component model you use.

Relevant Source Files

  • docs/builders/vite.mdx — Defines Storybook’s Vite builder, explains why it is the default builder, describes automatic reuse of Vite configuration, documents viteFinal, viteConfigPath, configLoader, and TypeScript configuration, and gives migration guidance for Webpack-to-Vite projects.

Core Primitives

The first primitive is the Storybook framework entry in .storybook/main.js or .storybook/main.ts. For a Vue 3 Vite application, choose the Vue 3 Vite framework entry; for a Svelte application built directly with Vite, choose the Svelte Vite entry; and for a SvelteKit application, choose the SvelteKit entry. The framework package wires the renderer and the builder together, so the same Storybook concepts remain available across all three: Component Story Format story files, args, controls, docs generation, loaders, decorators, and play functions. The renderer decides how a component is rendered; the Vite builder decides how the source modules are bundled and refreshed.

The second primitive is the Vite configuration file. Storybook’s Vite builder documentation says the builder merges its own defaults with the application’s existing Vite configuration, and recommends applying most configuration directly in vite.config.js or vite.config.ts for the best experience. This matters for Vue and Svelte because many real projects already configure aliases, plugins, preprocessors, CSS handling, and environment behavior in Vite. Keeping those concerns in the app’s Vite config helps Storybook match the application rather than becoming a separate bundling environment. Sources: docs/builders/vite.mdx

The third primitive is .storybook/main.ts customization. When the application needs Storybook-only changes, the Vite builder exposes the asynchronous viteFinal function. It receives the default builder configuration and returns an updated configuration. Use this only when the shared Vite config is not enough, such as adding a Storybook-specific alias, conditionally changing behavior for a documentation build, or pointing Storybook at a nonstandard Vite config path. The builder docs also describe viteConfigPath for changing where Storybook looks for Vite config and configLoader for passing a loader option through to Vite. Sources: docs/builders/vite.mdx

Setup Flow

Start from an existing Vue, Svelte, or SvelteKit project that already runs with the required framework version and Vite. From the project root, initialize Storybook with the create command. The official framework pages use the same command for each integration:

npm create storybook@latest

After installation, run the development server with the generated project script:

npm run storybook

The installer detects the project and writes Storybook configuration under .storybook/. In a Vite-based project, the builder is already installed and configured when Storybook is initialized for the Vite application. If you are manually opting into the builder, the Vite builder docs describe installing the builder and updating .storybook/main.js|ts to include it. For these frameworks, prefer the framework-level package rather than thinking of Vite as a separate addon: the framework entry is what connects Vue or Svelte rendering to the Vite builder pipeline. Sources: docs/builders/vite.mdx

A compact framework selection reference looks like this:

Project typePublic setup intentRuntime expectation
Vue 3 with ViteUse the Vue 3 Vite Storybook frameworkVue 3 application built with Vite
Svelte with ViteUse the Svelte Vite Storybook frameworkSvelte application built with Vite
SvelteKitUse the SvelteKit Storybook frameworkSvelteKit application, also Vite-based

System-to-Code Mapping

The repository source for this page is the Vite builder documentation, which explains the shared build behavior behind all three framework choices. It states that Storybook’s Vite builder bundles components and stories with Vite, provides fast ESM-based startup and refresh behavior, and is the default builder. It also distinguishes two adoption cases: Vite applications can reuse their existing configuration, while applications coming from Webpack may gain speed but should remember that the execution environment differs from the original application bundler. Sources: docs/builders/vite.mdx

That distinction is especially useful when reasoning about Vue and Svelte projects. A Vue 3 Vite app and a Svelte Vite app should generally expect Storybook to reuse the same Vite-centered module graph as the app. A SvelteKit project is also Vite-based, but it has additional application conventions around routing and server/client boundaries. Storybook’s job is to render isolated UI states, so stories should focus on components and mock application context where necessary rather than assuming every SvelteKit runtime feature is available inside the isolated preview. The renderer supplies component semantics; Vite supplies module loading and HMR.

Configuration Reference

Use normal Vite configuration for shared app behavior, then reach for Storybook-specific hooks only when needed. The Vite builder docs recommend putting most configuration in vite.config.js|ts because Storybook automatically merges that config into its own. When a project has unusual requirements, configure the framework options and viteFinal in .storybook/main.ts. The important contract is that viteFinal is asynchronous, receives the default builder config, and returns the updated config, commonly using Vite’s mergeConfig helper. Sources: docs/builders/vite.mdx

// .storybook/main.ts
import { mergeConfig } from 'vite';
 
const config = {
  framework: {
    name: '@storybook/vue3-vite',
    options: {
      builder: {
        // Use this only when the Vite config is not in the project root.
        viteConfigPath: 'vite.config.ts',
      },
    },
  },
  async viteFinal(config) {
    return mergeConfig(config, {
      resolve: {
        alias: {
          '@': '/src',
        },
      },
    });
  },
};
 
export default config;

For Svelte Vite or SvelteKit, keep the same configuration shape and replace the framework name with the matching Storybook framework entry. The builder options remain builder options; the renderer-specific package remains the framework name. If Storybook should not load the application Vite config automatically, the builder docs note that viteConfigPath can point to a non-existent file. If Vite’s configuration loading behavior itself must change, set configLoader in builder options, matching Vite’s own --configLoader command-line concept. Sources: docs/builders/vite.mdx

Migration and Next Steps

When moving a Vue or Svelte project from a Webpack-oriented Storybook setup to a Vite-oriented one, start with less configuration rather than porting every loader and plugin. Storybook’s Vite builder docs explicitly recommend beginning with no Storybook-specific Vite configuration and adding only what the project proves it needs. Styles usually require less custom handling under Vite, and many old Webpack loader rules can disappear. If the application depends on custom transforms, express them as Vite plugins or shared Vite config first, then add viteFinal only for Storybook-specific differences. Sources: docs/builders/vite.mdx

Next, write stories using the same Storybook authoring model used by other renderers: export component metadata, create named story variants, pass data through args, add decorators for providers or layout, and use play functions for interactions. Read the writing-stories pages after setup, then return to the Vite builder page when configuration diverges from the app. For SvelteKit, also audit whether a component assumes routing, server data, or browser-only APIs, and provide mocks or wrapper components so the story remains an isolated, deterministic UI example.