Storybook 8 vs Ladle vs Histoire: Component Development 2026
·PkgPulse Team
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
| Package | Weekly Downloads | Trend |
|---|---|---|
@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 8 | Ladle | Histoire | |
|---|---|---|---|
| Framework | React, Vue, Svelte, etc. | React only | Vue 3 focused |
| Startup speed | Medium (Vite) | Fast | Fast (Vite) |
| Addons | ✅ 1000+ | ❌ Minimal | ❌ Limited |
| Interaction tests | ✅ play() | ❌ | ❌ |
| Chromatic | ✅ | ❌ | ❌ |
| A11y checks | ✅ Addon | ❌ | ❌ |
| Autodocs | ✅ | ❌ | Partial |
| 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
Compare Storybook, Ladle, and Histoire download trends on PkgPulse.