Storybook for Angular with Vite
Storybook for Angular with Vite is a framework that makes it easy to develop and test UI components in isolation for Angular applications. It uses Vite for faster builds, better performance, and Storybook Testing support. The Vite transform pipeline is powered by the AnalogJS Vite plugin.
Install
To install Storybook in an existing Angular project, run this command in your project's root directory:
npm create storybook@latestYou can then get started writing stories, running tests and documenting your components. For more control over the installation process, refer to the installation guide.
Requirements
Angular ≥ 21
Vite ≥ 8
Choose between Vite and Webpack
@storybook/angular-vite is the Vite-based Angular framework. Use it when you want:
- Faster builds and HMR than the Webpack-based
@storybook/angularframework - Full support for the Vitest addon and in-browser component testing
- A simpler configuration without Babel and a smaller dependency footprint
Use @storybook/angular (Webpack 5) if your project requires Angular ≤ 20 or has custom Webpack configurations you cannot migrate.
Run Storybook
You can run Storybook either with the standard Storybook CLI or, like @storybook/angular, through Angular CLI builders. Both paths share the same configuration.
With the Storybook CLI
npm run storybookTo build:
npm run build-storybookThe output lands in the configured outputDir (default storybook-static).
With the Angular CLI
Register the start-storybook and build-storybook builders in angular.json:
{
"projects": {
"your-project": {
"architect": {
"storybook": {
"builder": "@storybook/angular-vite:start-storybook",
"options": {
"configDir": ".storybook",
"port": 6006,
},
},
"build-storybook": {
"builder": "@storybook/angular-vite:build-storybook",
"options": {
"configDir": ".storybook",
"outputDir": "dist/storybook/your-project",
},
},
},
},
},
}Then run them with ng run your-project:storybook and ng run your-project:build-storybook.
Unlike the Webpack-based @storybook/angular, these builders do not take a browserTarget. Vite resolves your project's TypeScript and assets directly, so no Angular build target reference is required. Builder schemas live alongside the source: start-storybook, build-storybook.
Configure
The authoring surface (stories, decorators, parameters, compodoc setup, moduleMetadata, and applicationConfig) is identical to @storybook/angular. Existing stories migrate without changes. The sections below describe every configuration option available in this framework.
Compodoc
JSDoc comments above components, directives, and other parts of your Angular code are picked up by Compodoc and surfaced as automatic documentation in Storybook. Comments above @Input and @Output members are especially useful because those are the elements Storybook exposes as controls.
Automatic setup
When installing Storybook via npx storybook@latest init, Compodoc can be set up automatically.
Manual setup
Install Compodoc:
npm install --save-dev @compodoc/compodocThen configure Storybook to run Compodoc via framework.options in your .storybook/main.ts:
import type { StorybookConfig } from '@storybook/angular-vite';
const config: StorybookConfig = {
framework: {
name: '@storybook/angular-vite',
options: {
compodoc: true,
compodocArgs: ['-e', 'json', '-d', '.'],
},
},
};
export default config;compodoc defaults to true and compodocArgs defaults to ['-e', 'json', '-d', '.']. When enabled, the framework preset generates documentation.json on cold start if the file does not already exist.
Supported invocation paths
ng run app:storybook: Usesangular.jsonfor Angular build settings. The framework preset runs Compodoc at cold start sodocumentation.jsonis generated before stories render.- Vitest addon panel (inside a running
storybook dev): The addon-vitest child process inherits builder options from the parent process automatically; no extra configuration is needed. - Standalone
yarn vitest(without a parentstorybook dev): Supported viastorybookAngularVitestfrom@storybook/angular-vite/vitest. Add it to the samepluginsarray asstorybookTestin yourvitest.config.ts; it forwards your Angular build options (styles, stylePreprocessorOptions, assets, zoneless) into the channel the framework already reads. If the env var is already set (e.g. a parentstorybook devis running), the existing value wins and a warning is logged so you know which options are active.
Application-wide providers
If your component relies on application-wide providers (such as those returned by provide-style functions or set up by any module using the forRoot pattern), apply the applicationConfig decorator to supply them via the bootstrapApplication function.
import { type Meta, type StoryObj, applicationConfig } from '@storybook/angular-vite';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { ChipsModule } from './angular-src/chips.module';
const meta: Meta<ChipsModule> = {
component: ChipsModule,
decorators: [
// Apply application config to all stories
applicationConfig({
// List of providers and environment providers that should be available to the root component and all its children.
providers: [
// ...
// Register application-wide providers with provide-style functions, e.g.
provideAnimationsAsync(),
// You can also pull providers in from an NgModule with importProvidersFrom(SomeModule)
],
}),
],
};
export default meta;
type Story = StoryObj<ChipsModule>;
export const WithCustomApplicationProvider: Story = {
render: () => ({
// Apply application config to a specific story
applicationConfig: {
// The providers will be merged with the ones defined in the applicationConfig decorator's providers array of the global meta object
providers: [
/* ... */
],
},
}),
};Angular dependencies
If your component has dependencies on other Angular directives and modules, supply them using the moduleMetadata decorator either for all stories of a component or for individual stories.
import { Meta, moduleMetadata, StoryObj } from '@storybook/angular-vite';
import { YourComponent } from './your.component';
const meta: Meta<YourComponent> = {
component: YourComponent,
decorators: [
moduleMetadata({
imports: [
//...
],
declarations: [
//...
],
providers: [
//...
],
}),
],
};
export default meta;
type Story = StoryObj<YourComponent>;
export const Base: Story = {};Zoneless change detection
By default, this framework runs with zoneless change detection (zoneless: true). To opt into Zone.js-based change detection, set the zoneless option to false on the Storybook builder target in your angular.json:
"storybook": {
"builder": "@storybook/angular-vite:start-storybook",
"options": {
"zoneless": false,
},
},When zoneless is false, zone.js is automatically imported at the start of the preview.
Custom Vite configuration
You can extend the Vite configuration used by Storybook in your .storybook/main.ts file via viteFinal:
import type { StorybookConfig } from '@storybook/angular-vite';
const config: StorybookConfig = {
framework: '@storybook/angular-vite',
async viteFinal(config) {
const { mergeConfig } = await import('vite');
return mergeConfig(config, {
// your overrides
});
},
};
export default config;TypeScript paths
Storybook reads your tsconfig.json's baseUrl and paths settings and maps them into Vite's resolver, so TypeScript path aliases work without additional configuration.
Migration from @storybook/angular
Automatic migration
Run the Storybook automigration command to update your project automatically:
npx storybook automigrateManual migration
First, install the framework:
npm install --save-dev @storybook/angular-viteThen, update your .storybook/main.ts to change the framework property:
- import type { StorybookConfig } from '@storybook/angular';
+ import type { StorybookConfig } from '@storybook/angular-vite';
const config: StorybookConfig = {
// ...
- framework: '@storybook/angular',
+ framework: '@storybook/angular-vite',
};
export default config;If your existing angular.json already declares Storybook architect targets, update the builder references to use the new framework and drop the browserTarget option (see why):
{
"projects": {
"your-project": {
"architect": {
"storybook": {
- "builder": "@storybook/angular:start-storybook",
+ "builder": "@storybook/angular-vite:start-storybook",
"options": {
- "browserTarget": "your-project:build",
//... other options
},
},
"build-storybook": {
- "builder": "@storybook/angular:build-storybook",
+ "builder": "@storybook/angular-vite:build-storybook",
"options": {
- "browserTarget": "your-project:build",
//... other options
},
},
},
},
},
}If you would rather invoke Storybook directly, you can also remove the architect entries entirely and switch to storybook dev and storybook build.
If your configuration contains a webpackFinal hook, you will need to migrate it to viteFinal.
Vitest integration
Because @storybook/angular-vite is a Vite-based framework, it supports the Vitest addon for running component tests directly inside Storybook.
Install the addon
Run the following command to install and configure the addon automatically:
npx storybook add @storybook/addon-vitestThis will install @storybook/addon-vitest, configure Vitest in browser mode using Playwright's Chromium browser, and set up the Vitest plugin. For Angular projects, the installer also scaffolds storybookAngularVitest({}) next to storybookTest() in your vitest.config.ts so standalone yarn vitest runs pick up your Angular build options automatically.
Refer to the Vitest addon guide for the full configuration reference.
Standalone yarn vitest (without Storybook dev)
When you run yarn vitest outside of a running storybook dev, the storybookAngularVitest helper from @storybook/angular-vite/vitest forwards your Angular build options (styles, stylePreprocessorOptions, assets, zoneless) into the channel the framework reads. Place it in the same plugins array as storybookTest:
import { storybookAngularVitest } from '@storybook/angular-vite/vitest';
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
projects: [
{
plugins: [
// Bridge Angular build options into standalone vitest runs.
// When a parent `storybook dev` is running, the existing env var
// wins and a warning is logged; options here are ignored in that run.
storybookAngularVitest({
// styles: ['src/styles.css'],
// stylePreprocessorOptions: { includePaths: ['src'] },
// assets: [{ glob: '**/*', input: 'src/assets', output: 'assets' }],
// zoneless: true,
}),
storybookTest({ configDir: '.storybook' }),
],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
},
],
},
});If you use a Vitest workspace file or a setup other than storybookTest(), follow the Analog Storybook integration docs instead.
FAQ
Does this framework support Angular CLI builders?
Yes. @storybook/angular-vite ships start-storybook and build-storybook builders so you can run ng run your-project:storybook and ng run your-project:build-storybook. See Run Storybook → With the Angular CLI for the angular.json setup. You can also invoke Storybook directly with storybook dev / storybook build.
Can I use this with Angular 20 or earlier?
No. This framework requires Angular 21. For earlier Angular versions, use @storybook/angular.
Are my existing stories compatible?
Yes. The story format (CSF), decorators (moduleMetadata, applicationConfig, componentWrapperDecorator), parameters, and compodoc integration are identical between @storybook/angular and @storybook/angular-vite. Stories files will only require changes to the framework import paths (handled automatically during migration).
Should I use @storybook/angular or @storybook/angular-vite?
Use @storybook/angular-vite if you are on Angular 21 and want faster builds and the Vitest addon. Use @storybook/angular if you need Angular 18–20 or existing Webpack-based tooling you cannot migrate. Both frameworks support Angular CLI builders.
API
Options
You can pass an options object for additional configuration:
import type { StorybookConfig } from '@storybook/angular-vite';
const config: StorybookConfig = {
framework: {
name: '@storybook/angular-vite',
options: {
// ...
},
},
};
export default config;The available options are:
builder
Type: Record<string, any>
Configure options for the framework's builder. Available options can be found in the Vite builder docs.
jit
Type: boolean
Default: true
Whether to use Angular's JIT compiler. Passed to the AnalogJS Vite plugin.
liveReload
Type: boolean
Default: false
Whether to enable live-reload in the AnalogJS Vite plugin.
tsconfig
Type: string
Default: ./.storybook/tsconfig.json
Path to the TypeScript configuration file, relative to the workspace root. Passed to the AnalogJS Vite plugin.
inlineStylesExtension
Type: string
Default: 'css'
File extension used for inline component styles. Passed to the AnalogJS Vite plugin.
compodoc
Type: boolean
Default: true
Whether to run Compodoc on cold start to generate documentation.json. When true, the framework preset invokes Compodoc once if documentation.json does not already exist. Set to false to skip generation entirely (e.g. when you manage Compodoc outside of Storybook).
compodocArgs
Type: string[]
Default: ['-e', 'json', '-d', '.']
Arguments passed to the @compodoc/compodoc CLI when compodoc is true. The defaults produce a documentation.json file in the workspace root.
