Frontend workshop for building, documenting, and testing UI components in isolation across frameworks
npx @tessl/cli install tessl/npm-storybook@9.1.0Storybook is a comprehensive frontend workshop for building, documenting, and testing UI components in isolation across multiple frameworks including React, Vue, Angular, Svelte, and Web Components. It provides a complete development environment with CLI tools, development server, visual testing capabilities, and an extensive addon ecosystem for enhanced functionality.
npm install storybookThe Storybook package provides multiple import paths for different functionalities:
// Core functionality
import { composeStory, composeStories } from "storybook/preview-api";
import { action, actions } from "storybook/actions";
import { expect, userEvent } from "storybook/test";
import { create, themes } from "storybook/theming";
// Manager API (experimental)
import { useStorybookApi } from "storybook/manager-api";
// Internal APIs (advanced usage)
import { styled, css } from "storybook/internal/theming";
import { Button, Modal } from "storybook/internal/components";
import { logger } from "storybook/internal/client-logger";For CommonJS:
const { composeStory, composeStories } = require("storybook/preview-api");
const { action, actions } = require("storybook/actions");
const { expect, userEvent } = require("storybook/test");
const { create, themes } = require("storybook/theming");import { composeStory, setProjectAnnotations } from "storybook/preview-api";
import { action } from "storybook/actions";
import { expect, userEvent, within } from "storybook/test";
// Set up project-level configuration
setProjectAnnotations({
parameters: {
backgrounds: { default: 'light' }
}
});
// Compose a story for testing
const ComposedButton = composeStory(ButtonStory, ButtonMeta);
// Use in tests
test('button handles click', async () => {
const handleClick = action('clicked');
render(<ComposedButton onClick={handleClick} />);
const button = screen.getByRole('button');
await userEvent.click(button);
expect(handleClick).toHaveBeenCalledOnce();
});Storybook is built around several key architectural components:
Command-line interface for project initialization, development server, build operations, and project management. Essential for setting up and managing Storybook projects.
// Primary CLI commands (via storybook binary)
storybook dev [options] // Start development server
storybook build [options] // Build static Storybook
storybook init [options] // Initialize Storybook in project
storybook add <addon> // Add an addon
storybook remove <addon> // Remove an addon
storybook upgrade // Upgrade Storybook packages
storybook info // Environment debugging info
storybook migrate // Run migration scripts
storybook sandbox // Create sandbox templatesCore functionality for composing and testing stories outside of the Storybook environment. Essential for unit testing, integration testing, and component validation workflows.
function composeStory<TRenderer, TArgs>(
story: Story<TRenderer, TArgs>,
meta: Meta<TRenderer, TArgs>,
projectAnnotations?: ProjectAnnotations<TRenderer>
): ComposedStory<TRenderer, TArgs>;
function composeStories<TModule extends StoriesModule>(
module: TModule,
projectAnnotations?: ProjectAnnotations<TRenderer>
): ComposedStoryModule<TModule>;
function setProjectAnnotations<TRenderer>(
annotations: ProjectAnnotations<TRenderer>
): void;Action tracking system for logging and monitoring component interactions and events. Provides automatic event capture and manual action creation with configurable options.
function action(name: string, options?: ActionOptions): HandlerFunction;
function actions<T extends string>(...handlers: T[]): ActionsMap<T>;
function actions<T extends string>(
handlerMap: Record<T, string>,
options?: ActionOptions
): ActionsMap<T>;
interface ActionOptions {
depth?: number;
clearOnStoryChange?: boolean;
limit?: number;
implicit?: boolean;
id?: string;
}Comprehensive testing utilities built on top of popular testing libraries with Storybook-specific instrumentation and integrations.
const expect: Expect;
const userEvent: UserEvent;
interface MockUtilities {
mock(path: string | Promise<unknown>, factory?: ModuleMockOptions): void;
}
const sb: MockUtilities;Complete theming system for customizing Storybook's UI appearance with pre-built themes and custom theme creation capabilities.
function create(vars?: ThemeVarsPartial, rest?: object): ThemeVars;
const themes: {
light: ThemeVars;
dark: ThemeVars;
normal: ThemeVars;
};
interface ThemeVars {
base: 'light' | 'dark';
colorPrimary: string;
colorSecondary: string;
appBg: string;
appContentBg: string;
appPreviewBg: string;
// ... extensive theming properties
}Visual highlighting system for emphasizing specific DOM elements within stories, useful for documentation and interactive tutorials.
const HIGHLIGHT = 'storybook/highlight';
const REMOVE_HIGHLIGHT = 'storybook/remove-highlight';
const RESET_HIGHLIGHT = 'storybook/reset-highlight';
const SCROLL_INTO_VIEW = 'storybook/scroll-into-view';
interface HighlightOptions {
elements: string[] | HTMLElement[];
color?: string;
style?: 'solid' | 'dashed' | 'dotted';
}Viewport control system for testing components across different screen sizes and device configurations.
interface Viewport {
name: string;
styles: ViewportStyles;
type?: 'desktop' | 'mobile' | 'tablet' | 'other';
}
interface ViewportStyles {
height: string;
width: string;
}
type ViewportMap = Record<string, Viewport>;Experimental API for Storybook manager-side state management and UI customization. Provides access to stories, addons, and global state.
function useStorybookApi(): API;
function useStorybookState(): State;
function useChannel(): Channel;
interface API {
selectStory: (storyId: string) => void;
getCurrentStoryData: () => Story | undefined;
setOptions: (options: Options) => void;
addPanel: (id: string, panel: Panel) => void;
}Framework-specific packages providing deep integration with popular frontend frameworks and their build tools.
// Framework packages
import type { Meta, StoryObj } from "@storybook/react";
import type { Meta, StoryObj } from "@storybook/vue3";
import type { Meta, StoryObj } from "@storybook/angular";
import type { Meta, StoryObj } from "@storybook/svelte";
// Builder packages
import { viteFinal } from "@storybook/builder-vite";
import { webpackFinal } from "@storybook/builder-webpack5";Advanced APIs and UI components for building custom addons and extending Storybook functionality. These are internal APIs that may change between versions.
// Internal theming (Emotion-based)
import { styled, css, keyframes, ThemeProvider } from "storybook/internal/theming";
// UI Components
import { Button, Modal, Tabs, Toolbar } from "storybook/internal/components";
// Core utilities
import { logger } from "storybook/internal/client-logger";
import { Channel } from "storybook/internal/channels";
// CSF tools
import { loadCsf, writeCsf } from "storybook/internal/csf-tools";Note: Internal APIs are subject to change and should be used with caution. They are primarily intended for addon development and advanced customization scenarios.
interface Story<TRenderer = unknown, TArgs = unknown> {
(args: TArgs, context: StoryContext<TRenderer>): unknown;
storyName?: string;
parameters?: Parameters;
args?: Partial<TArgs>;
argTypes?: ArgTypes<TArgs>;
decorators?: DecoratorFunction<TRenderer, TArgs>[];
}
interface Meta<TRenderer = unknown, TArgs = unknown> {
title?: string;
component?: unknown;
parameters?: Parameters;
args?: Partial<TArgs>;
argTypes?: ArgTypes<TArgs>;
decorators?: DecoratorFunction<TRenderer, TArgs>[];
}
interface StoryContext<TRenderer = unknown> {
id: string;
name: string;
title: string;
parameters: Parameters;
args: Args;
argTypes: ArgTypes;
globals: Args;
viewMode: ViewMode;
loaded: Record<string, unknown>;
}
interface ComposedStory<TRenderer = unknown, TArgs = unknown> {
(args?: Partial<TArgs>): unknown;
id: string;
storyName: string;
args: TArgs;
parameters: Parameters;
argTypes: ArgTypes<TArgs>;
play?: PlayFunction<TRenderer, TArgs>;
}
type ProjectAnnotations<TRenderer = unknown> = {
parameters?: Parameters;
decorators?: DecoratorFunction<TRenderer>[];
args?: Args;
argTypes?: ArgTypes;
globals?: Args;
globalTypes?: GlobalTypes;
};