Skip to main content

Storybook 8 vs Ladle vs Histoire: Component Dev 2026

·PkgPulse Team
0

TL;DR

Storybook 8 remains the standard for React component development — 30M+ downloads/week, mature ecosystem, test runner, Chromatic integration. Ladle is 10-50x faster to start (pure Vite, no custom webpack), making it compelling for large codebases where Storybook startup was painful. Histoire is Vite-native for Vue 3 — the Storybook equivalent for the Vue ecosystem. For most teams: Storybook 8 with Vite builder. For small/medium React projects prioritizing speed: Ladle.

Key Takeaways

  • Storybook 8: Vite-based by default (finally), 30M downloads/week, full ecosystem
  • Ladle: Pure Vite, no config needed, 10-50x faster startup, limited addon ecosystem
  • Histoire: Vue 3 focused, excellent Vite integration, Nuxt support
  • Speed: Ladle (1-2s start) vs Storybook 8 Vite (5-15s start) vs Storybook 8 Webpack (30s+)
  • Addons: Storybook has 1000+ addons; Ladle/Histoire have minimal ecosystems
  • Migration: Easy to migrate from Storybook to Ladle (same CSF format)

Downloads

PackageWeekly DownloadsTrend
@storybook/react~3M→ Stable
storybook~5M↑ Growing
@ladle/react~100K↑ Growing
histoire~30K↑ Growing (Vue)

Storybook 8: The Standard

npx storybook@latest init
# Storybook 8 uses Vite by default for React projects
// stories/Button.stories.tsx — Component Story Format (CSF3):
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from '../components/Button';
import { userEvent, within, expect } from '@storybook/test';

const meta: Meta<typeof Button> = {
  title: 'UI/Button',
  component: Button,
  tags: ['autodocs'],  // Auto-generate docs from props
  parameters: {
    layout: 'centered',  // Center in canvas
    backgrounds: {
      default: 'light',
    },
  },
  argTypes: {
    variant: {
      control: 'select',
      options: ['default', 'outline', 'destructive'],
    },
    size: {
      control: 'radio',
      options: ['sm', 'default', 'lg'],
    },
    onClick: { action: 'clicked' },
  },
};
export default meta;

type Story = StoryObj<typeof Button>;

export const Default: Story = {
  args: {
    children: 'Button',
    variant: 'default',
  },
};

export const AllVariants: Story = {
  render: () => (
    <div className="flex gap-2">
      <Button variant="default">Default</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="destructive">Delete</Button>
    </div>
  ),
};

// Interaction test (runs in test runner):
export const ClickInteraction: Story = {
  args: { children: 'Click Me', onClick: fn() },
  play: async ({ canvasElement, args }) => {
    const canvas = within(canvasElement);
    await userEvent.click(canvas.getByRole('button'));
    await expect(args.onClick).toHaveBeenCalled();
  },
};
# Storybook 8 commands:
npx storybook dev -p 6006        # Start dev server
npx storybook build               # Static build for deployment
npx test-storybook                # Run interaction tests
npx chromatic --project-token=... # Visual regression testing

Storybook 8 New Features

Storybook 8 improvements:
  → Vite as default bundler (was webpack — 3-10x faster)
  → @storybook/test replaces testing-library as built-in
  → Vitest integration for unit + component tests
  → Portable stories (use stories in Vitest)
  → Improved TypeScript types
  → Story decorators with TypeScript inference

Ladle: Vite-Native Speed

npm install -D @ladle/react
# Zero config! Works with any Vite project.
Ladle file structure — same as Storybook!
  → Uses CSF (Component Story Format)
  → Files: *.stories.tsx
  → Same Meta and StoryObj types
// Ladle uses the exact same story format as Storybook:
// button.stories.tsx — compatible with both!

import type { StoryDefault, Story } from '@ladle/react';

export default {
  title: 'UI/Button',
} satisfies StoryDefault;

export const Default: Story = () => <Button>Click me</Button>;

export const Variants: Story = () => (
  <div className="flex gap-2">
    <Button variant="default">Default</Button>
    <Button variant="outline">Outline</Button>
    <Button variant="destructive">Delete</Button>
  </div>
);
// package.json — add Ladle scripts:
{
  "scripts": {
    "ladle": "ladle serve",    // Dev server
    "ladle:build": "ladle build"  // Static export
  }
}

Ladle Speed Comparison

Project: 150 components, 450+ stories

Storybook 8 (Vite builder):
  Cold start: 12s
  Hot reload: 200ms

Ladle:
  Cold start: 1.8s  (6.7x faster)
  Hot reload: 80ms  (2.5x faster)

For a large enterprise codebase (500 components):
  Storybook 8 Vite: 30-45s cold start
  Ladle: 3-5s cold start
  Storybook 8 Webpack: 2-4 minutes cold start

Ladle Limitations

Ladle missing vs Storybook:
  ❌ No addon ecosystem (no a11y, viewport, backgrounds addon)
  ❌ No interaction tests (no play() functions)
  ❌ No Chromatic visual regression
  ❌ No test runner
  ❌ No MDX docs pages
  ❌ Less active development

Ladle use case:
  → Dev environment only (fast iteration)
  → Pair with Vitest/Playwright for testing
  → Teams who found Storybook too slow

Histoire: Vue 3 Native

npm install -D histoire @histoire/plugin-vue
# For Nuxt:
npm install -D histoire @histoire/plugin-nuxt
// histoire.config.ts:
import { defineConfig } from 'histoire';
import { HstVue } from '@histoire/plugin-vue';

export default defineConfig({
  plugins: [HstVue()],
  setupFile: './src/histoire.setup.ts',
  theme: {
    title: 'My Component Library',
    logo: { light: '/logo.svg', dark: '/logo-dark.svg' },
  },
});
<!-- Button.story.vue — Histoire story format: -->
<script setup lang="ts">
import { reactive } from 'vue';
import Button from './Button.vue';

const state = reactive({
  variant: 'default' as 'default' | 'outline' | 'destructive',
  label: 'Click me',
  disabled: false,
});
</script>

<template>
  <Story title="UI/Button">
    <Variant title="Default">
      <Button :variant="state.variant" :disabled="state.disabled">
        {{ state.label }}
      </Button>
    </Variant>
    
    <Variant title="All Variants">
      <div class="flex gap-2">
        <Button variant="default">Default</Button>
        <Button variant="outline">Outline</Button>
        <Button variant="destructive">Destructive</Button>
      </div>
    </Variant>
    
    <template #controls>
      <HstSelect v-model="state.variant" :options="['default','outline','destructive']"
        title="Variant" />
      <HstText v-model="state.label" title="Label" />
      <HstCheckbox v-model="state.disabled" title="Disabled" />
    </template>
  </Story>
</template>

Feature Comparison

Storybook 8LadleHistoire
FrameworkReact, Vue, Svelte, etc.React onlyVue 3 focused
Startup speedMedium (Vite)FastFast (Vite)
Addons✅ 1000+❌ Minimal❌ Limited
Interaction testsplay()
Chromatic
A11y checks✅ Addon
AutodocsPartial
Portable stories✅ (v8)
Vue support@storybook/vue3✅ Native

Decision Guide

Use Storybook 8 if:
  → Design system or component library (documentation matters)
  → Need interaction tests + Chromatic visual regression
  → Team already knows Storybook
  → Multiple frameworks in one project

Use Ladle if:
  → React only project
  → Storybook startup time is a pain point
  → Dev environment usage (no need for test runner)
  → Migrating from Storybook but want speed improvement

Use Histoire if:
  → Vue 3 or Nuxt project
  → Want Vite-native Vue component development
  → More visual control panel options than Storybook Vue

Testing Integration: Where the Tools Diverge Most

The most significant practical difference between Storybook 8, Ladle, and Histoire in 2026 is their testing story. Storybook 8 ships a complete testing ecosystem: @storybook/test provides userEvent, expect, and within utilities modeled on Testing Library, and the play() function in a story runs interaction tests against the rendered component. These tests execute in the browser — real DOM, real events — and can be run in CI via test-storybook or integrated into Vitest via "portable stories."

Portable stories are a Storybook 8 feature that deserves more attention: composeStories() from @storybook/react lets you import your story definitions and mount them inside Vitest or Playwright tests. This means the same story used for documentation doubles as a test fixture, eliminating the need to maintain separate test setup code for the same scenarios. For teams maintaining a component library with hundreds of variants, this DX improvement is substantial.

Ladle has no equivalent testing support. It's explicitly a development tool — fast to start, great for visual iteration, but you need a separate test setup (Vitest with Testing Library, Playwright component tests) for anything beyond visual inspection. This isn't necessarily a problem: many teams already have solid Vitest setups and don't need Storybook's test runner. But if your team expects the documentation tool to also be the test harness, Ladle leaves a gap.

Histoire is in a similar position to Ladle on testing — it renders Vue components for documentation but doesn't provide a test runner. The Vue testing story is typically separate: Vitest with @vue/test-utils handles unit and component tests, while Histoire handles documentation. The histoire team has indicated interest in testing integration but it hasn't materialized in 2026.

Storybook 8 Vite Builder: Closing the Speed Gap

Storybook's historical reputation for slowness was earned with its webpack-based architecture — cold starts measured in minutes for large component libraries were genuinely painful. Storybook 8 addresses this by defaulting to the Vite builder for React (and other frameworks with Vite support), which eliminates most of that pain.

The Vite builder uses Vite's native ESM-based dev server, so individual story modules are loaded on demand rather than bundled upfront. This means the cold start time scales with the number of stories actually opened, not the total story count. For a library with 500 components, Storybook 8 Vite starts in 5-15 seconds on an M-series Mac — a 10-15x improvement over the webpack builder and much closer to Ladle's 1-3 second startup.

The remaining gap between Storybook 8 Vite and Ladle comes from Storybook's additional boot overhead: loading the addon registry, checking for updates, initializing the manager UI, and setting up the testing infrastructure. Ladle skips all of this — it's a thin wrapper around Vite with story discovery. For teams where the remaining 5-10 second difference matters (developers who frequently stop/start their story server), Ladle's speed advantage is still real.

One practical note: if you're currently on Storybook 7 or earlier with the webpack builder and evaluating Ladle purely for speed, upgrading to Storybook 8 with the Vite builder (npx storybook@latest upgrade) often closes the gap enough to stay in the ecosystem without migrating story files.

Component Documentation and Design System Workflows

For teams publishing a design system or component library — as opposed to using Storybook purely as a development tool — Storybook's documentation capabilities are in a different category from Ladle and Histoire. Storybook's autodocs tag automatically generates API documentation pages from JSDoc comments and TypeScript prop types, creating a browsable reference for every component's props, default values, and type signatures without manual authoring.

The Chromatic integration extends this into visual regression testing at the component level. Each story becomes a visual baseline snapshot, and Chromatic detects pixel-level changes across every story on every PR. For design systems where visual consistency is critical and changes are reviewed by both engineers and designers, this workflow is a practical superpower that Ladle and Histoire cannot replicate.

Histoire's unique strength for Vue teams is its controls panel. The HstSelect, HstText, HstCheckbox, and similar controls defined in <template #controls> give story authors fine-grained interactive controls for component state that are more ergonomic to write in Vue's template syntax than Storybook's argTypes configuration. For Vue developers who found Storybook's configuration verbose, Histoire often feels like a better fit for the Vue component development mental model.

Compare Storybook, Ladle, and Histoire download trends on PkgPulse.

When to Use Each

The choice between these three tools depends on your project's scale and framework allegiance.

Storybook 8 is the default choice for any team that:

  • Works across multiple frameworks (React, Vue, Angular, Svelte, Web Components)
  • Needs a dedicated design system documentation platform
  • Wants the full addon ecosystem (visual testing, accessibility checks, interaction testing)
  • Is building a component library for public or internal consumption

Ladle is the choice when you:

  • Have a pure React + Vite project and want zero-config story tooling
  • Find Storybook too heavy for a small or medium component library
  • Want instant hot reload without the Storybook overhead
  • Primarily use stories for development, not as public documentation

Histoire is the choice when you:

  • Work in a Vue 3 or Svelte project and want first-class framework support
  • Prefer a simpler, more opinionated API over Storybook's flexibility
  • Want built-in story variants with less boilerplate than Storybook args

In practice, most large teams and design systems use Storybook — the ecosystem and documentation tooling justifies the setup cost. Smaller teams and solo developers working in React-only projects often find Ladle a better fit. Vue and Svelte teams should evaluate Histoire before defaulting to Storybook, as Histoire's native Vue integration provides a significantly better authoring experience.

The migration path between these tools is smoother than it appears. Storybook and Ladle share the Component Story Format (CSF3), so existing story files work in both environments without changes. Teams can run Ladle alongside Storybook during evaluation — both tools read the same *.stories.tsx files and produce comparable preview interfaces. This compatibility means the decision is reversible: adopting Ladle for faster local development does not lock you out of Storybook's test runner or Chromatic integration if requirements change.

See also: React vs Vue and React vs Svelte, Storybook 8 vs Ladle vs Histoire.

The 2026 JavaScript Stack Cheatsheet

One PDF: the best package for every category (ORMs, bundlers, auth, testing, state management). Used by 500+ devs. Free, updated monthly.