Component-driven development stopped being a nice-to-have around the time design systems became mandatory at most product companies, and by September 2026 the tool most teams reach for to build and test components in isolation is Storybook 10. The catch: React and Vue projects wire it up differently enough that copy-pasting a React tutorial into a Vue codebase (or vice versa) breaks in ways that waste an afternoon. This tutorial walks through a clean Storybook 10 install on both React 19.2.8 and Vue 3.5.41, adds component testing with the official Vitest addon, layers in accessibility checks, and wires up visual regression testing with Chromatic — end to end, with the exact commands and config for each framework side by side.
By the end you will have two working Storybook instances (one React, one Vue), a shared understanding of where the two setups diverge, and a CI pipeline that runs component tests and visual diffs on every pull request. Total time: roughly 100 minutes if you follow the steps in order.
Why Storybook Setup Differs Between React and Vue in 2026
Storybook 10, released in October 2025, made one deliberate breaking change: the package is now ESM-only. According to the official Storybook 10.0 release notes, that single change cuts install size by 29% and ships unminified dist code so stack traces during debugging actually point at real source lines instead of a wall of minified garbage. That change alone affects both frameworks equally, but the framework-specific pieces do not.
Since Storybook 8, the project no longer requires React as a peer dependency when you are running a non-React renderer — a detail that used to trip up Vue teams who ended up with a phantom React install sitting in node_modules for no reason. Vue 3 Storybooks build cleaner today because of it. React vs Vue Storybook setup also diverges on story typing (React leans on typesafe CSF factories that shipped as a 10.0 preview feature, Vue still uses the standard CSF3 object format with defineComponent typing), on how each framework’s Vite plugin is wired into the builder, and on which testing story-to-test transform each framework’s Vitest addon uses under the hood. None of these are dealbreakers, but they are exactly the kind of small friction points that turn a “quick Storybook install” into a lost afternoon if you do not know they exist going in.
The Storybook Testing Addon Landscape: Which Package to Actually Install
Before you touch a terminal, it helps to know there are three different packages floating around the ecosystem that all claim to do “Vitest testing in Storybook,” and picking the wrong one wastes real time. The official, stable package for Storybook 10 is @storybook/addon-vitest. There is also @storybook/experimental-addon-test, an earlier package name that Storybook used while the feature was still in flux — its API is explicitly marked as subject to change, and it predates the stable rename. Separately, there is a community-maintained package literally named storybook_vitest_addon that adds a results panel showing Vitest output inside Storybook, which is a much narrower feature than the official addon’s story-to-test transformation. If a blog post, Stack Overflow answer, or AI-generated snippet tells you to install @storybook/experimental-addon-test for a new Storybook 10 project, treat that as outdated advice and reach for @storybook/addon-vitest instead.
| Package | Status | What It Actually Does |
|---|---|---|
| @storybook/addon-vitest | Stable, current for Storybook 10 | Transforms stories into Vitest component tests run in a real browser via Playwright; supports coverage and watch mode |
| @storybook/experimental-addon-test | Legacy naming, experimental API | Predecessor to addon-vitest with the same core goal, kept for backward compatibility in older projects |
| storybook_vitest_addon (community) | Third-party, narrower scope | Displays existing Vitest test results in a Storybook panel; does not generate tests from stories |
This distinction matters more than it looks. Teams that install the wrong package end up either duplicating test coverage (writing separate Vitest specs for components that already have stories) or getting confused when a tutorial they found online references APIs that were renamed a year earlier. Standardizing on @storybook/addon-vitest across both the React and Vue projects in this tutorial keeps the two setups genuinely comparable.
Prerequisites: Exact Versions You Need
Lock in these versions before you start. Mismatches between Node, Vite, and Storybook are the single most common cause of a broken install in this stack.
| Tool | Minimum Version Required | Version Used in This Tutorial |
|---|---|---|
| Node.js | 18.x (LTS strongly recommended) | 20.x LTS |
| React | 18.x | 19.2.8 (released July 21, 2026) |
| Vue | 3.x (Vue 2 is unsupported by Storybook 10) | 3.5.41 (released August 5, 2026) |
| Storybook | 10.0 | 10.x (latest via npx storybook@latest) |
| Vite | 5.x or later | 5.x, as bundled by each framework’s official Vite scaffold |
| @storybook/addon-vitest | N/A — install fresh | latest published version |
| Package manager | npm 9+, pnpm 8+, or yarn 3+ | npm (examples below; swap freely) |
You also need a code editor with TypeScript support (VS Code, Cursor, or similar), a GitHub account if you want to follow the CI section, and a free Chromatic account for the visual testing step — no credit card required for the free tier, which includes 5,000 snapshots per month according to Chromatic’s published pricing page.
Step 1: Scaffold the React 19 Project
Start with a clean Vite-powered React project rather than an older toolchain. Storybook 10’s Vite builder is what makes the React vs Vue Storybook setup fast in both directions, so keeping both projects on Vite from the start avoids builder mismatches later.
npm create vite@latest storybook-react-demo -- --template react-ts
cd storybook-react-demo
npm install
npm run dev
Confirm the dev server boots on the default Vite port before moving on. If it does not, fix that first — a broken base project will surface as a confusing Storybook error later, and you will waste time debugging the wrong layer.
Step 2: Install Storybook 10 in the React Project
Run the official initializer. It detects the Vite + React setup automatically and installs the matching framework package, addons, and a set of example stories so you have working code to reference immediately.
npx storybook@latest init
# When prompted, accept the detected React + Vite configuration.
# The CLI writes a .storybook/ directory and adds src/stories/ examples.
npm run storybook
Storybook should open at localhost:6006 with a sidebar full of example components — buttons, headers, and pages generated by the CLI. This confirms the React + Vite + Storybook 10 chain is wired correctly before you introduce any custom components.
Step 3: Write Your First React Component Story
Delete the generated example stories once you have confirmed the install works, then write a real one against a component you actually own. Storybook 10 uses Component Story Format 3 (CSF3) — the older storiesOf API and MDX story files were removed as part of the Storybook 8 breaking changes and never came back, so do not reach for either.
// src/components/Button.tsx
type ButtonProps = {
label: string;
variant?: "primary" | "secondary";
onClick?: () => void;
};
export function Button({ label, variant = "primary", onClick }: ButtonProps) {
return (
<button className={`btn btn-${variant}`} onClick={onClick}>
{label}
</button>
);
}
// src/components/Button.stories.tsx
import type { Meta, StoryObj } from "@storybook/react-vite";
import { Button } from "./Button";
const meta: Meta<typeof Button> = {
title: "Components/Button",
component: Button,
tags: ["autodocs"],
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = {
args: { label: "Save changes", variant: "primary" },
};
export const Secondary: Story = {
args: { label: "Cancel", variant: "secondary" },
};
The tags: ["autodocs"] line generates a documentation page automatically from the component’s TypeScript props, which saves you from writing prop tables by hand.
Step 4: Scaffold and Install Storybook 10 for Vue 3
Now set up the Vue side in a separate project. The commands are nearly parallel to the React flow, which is the point — but the resulting config file looks different once you open it.
npm create vite@latest storybook-vue-demo -- --template vue-ts
cd storybook-vue-demo
npm install
npx storybook@latest init
npm run storybook
Because Storybook 8 dropped the mandatory React peer dependency for non-React renderers, this install pulls in @storybook/vue3-vite without ever touching a React package. Check your package.json after the install finishes — if you see any react or react-dom entries, something detected the wrong framework and you should re-run the initializer after removing the stray dependencies.
Step 5: Write Your First Vue Component Story
Vue’s CSF3 stories look structurally similar to React’s but bind props and slots through the Vue-specific render or args pattern instead of JSX. This is the clearest side-by-side illustration of where React vs Vue Storybook setup actually diverges in day-to-day use.
<!-- src/components/Button.vue -->
<script setup lang="ts">
withDefaults(defineProps<{
label: string;
variant?: "primary" | "secondary";
}>(), { variant: "primary" });
defineEmits<{ click: [] }>();
</script>
<template>
<button :class="['btn', `btn-${variant}`]" @click="$emit('click')">
{{ label }}
</button>
</template>
// src/components/Button.stories.ts
import type { Meta, StoryObj } from "@storybook/vue3-vite";
import Button from "./Button.vue";
const meta: Meta<typeof Button> = {
title: "Components/Button",
component: Button,
tags: ["autodocs"],
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = {
args: { label: "Save changes", variant: "primary" },
};
export const Secondary: Story = {
args: { label: "Cancel", variant: "secondary" },
};
Notice the import path: @storybook/vue3-vite instead of @storybook/react-vite. Mixing these up — pasting a React import into a Vue stories file — is one of the most common copy-paste mistakes teams make when they maintain both a React and a Vue design system side by side.
Step 6: Add Component Testing With the Vitest Addon
Storybook 10’s testing story is built around @storybook/addon-vitest, which transforms every story you write into a real Vitest test that runs in an actual browser environment via Playwright’s browser mode, rather than a simulated DOM. According to Storybook’s official Vitest addon documentation, the addon can also calculate project test coverage directly from your stories and supports watch mode so tests re-run automatically as you edit components. Install it identically in both projects.
npm install --save-dev @storybook/addon-vitest vitest @vitest/browser playwright
npx playwright install chromium --with-deps
Register the addon in .storybook/main.ts for both the React and Vue projects — the entry is identical on both sides:
// .storybook/main.ts
import type { StorybookConfig } from "@storybook/react-vite"; // or vue3-vite
const config: StorybookConfig = {
stories: ["../src/**/*.stories.@(ts|tsx|js|jsx)"],
addons: [
"@storybook/addon-vitest",
"@storybook/addon-a11y",
"@storybook/addon-docs",
],
framework: {
name: "@storybook/react-vite", // swap to @storybook/vue3-vite in the Vue project
options: {},
},
};
export default config;
Run npx vitest --project=storybook (the project name the addon registers automatically) and every story you wrote in Steps 3 and 5 becomes a passing test with zero extra test code. This is the biggest practical win of the addon: you stop writing separate render tests for components that already have stories, because the stories are the tests.
Step 7: Add Accessibility Checks With the a11y Addon
With @storybook/addon-a11y already registered in Step 6’s config, every story now gets an “Accessibility” panel in the Storybook UI that runs axe-core rules against the rendered component. Install it explicitly if you have not already:
npm install --save-dev @storybook/addon-a11y
Open any story and click the Accessibility tab in the addons panel at the bottom of the Storybook UI. You will see violations, passes, and incomplete checks broken down by WCAG rule ID. For the Button component above, add explicit aria-label handling when the label prop is icon-only, and the addon will flag it immediately if you forget — catching accessibility regressions at component-authoring time instead of during a QA pass weeks later.
Step 8: Set Up Visual Regression Testing With Chromatic
Component tests catch logic regressions; they do not catch a designer’s CSS variable change silently breaking button padding across forty stories. That is what visual regression testing is for. Chromatic, built by the Storybook maintainers, snapshots every story and diffs it against the previous approved baseline.
npm install --save-dev chromatic
npx chromatic --project-token=<your-project-token>
Get the project token by connecting your repository at chromatic.com — one project per repository (so create separate Chromatic projects for the React and Vue demos). The free tier covers 5,000 snapshots a month, which Chromatic’s pricing page notes is roughly equivalent to 25,000 TurboSnaps thanks to its diffing optimizations; that is enough for a small-to-mid design system running CI on every pull request without hitting the cap. Paid tiers start at $179/month for 35,000 snapshots if your story count grows past that.
Step 9: Wire Storybook Into GitHub Actions CI
Manual test runs do not scale past a two-person team. Add a workflow that runs component tests and a Chromatic visual diff on every pull request, for both the React and Vue repos.
# .github/workflows/storybook.yml
name: Storybook Tests
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx playwright install chromium --with-deps
- run: npx vitest run --project=storybook
- uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
Store the Chromatic project token as a repository secret, never as a plaintext value in the workflow file. Once this merges, every pull request gets a status check for both component test pass/fail and a link to review any visual diffs before merge.
Step 10: Configure Sidebar Organization and Tag Filtering
As your story count grows past a few dozen components, an unorganized sidebar becomes unusable fast. Storybook 10 added tag filtering exclusion and configuration specifically to address this. Use tags to separate work-in-progress components from production-ready ones:
// .storybook/main.ts
const config: StorybookConfig = {
// ...existing config
tags: {
"work-in-progress": { excludeFromSidebar: true },
},
};
// In a story file:
export const ExperimentalVariant: Story = {
tags: ["work-in-progress"],
args: { label: "Draft button" },
};
This keeps the sidebar showing only what is ready for design review, while draft stories remain runnable locally and in tests — they are just hidden from the default navigation.
Step 11: Build a Static Storybook for Deployment
Beyond CI checks, most teams also publish a browsable static Storybook so designers and product managers can review components without cloning the repo. Both frameworks use the same build command.
npm run build-storybook
# outputs to storybook-static/ by default
npx serve storybook-static # quick local preview
Deploy the storybook-static directory to any static host — Chromatic hosts it automatically as part of the publish step in Step 8, or you can push it to Netlify, Vercel, or GitHub Pages if you want it decoupled from Chromatic entirely.
Step 12: Verify the Full Setup End to End
Run through this checklist on both the React and Vue projects before calling the setup done:
- Storybook dev server boots at
localhost:6006with your custom stories visible, not the CLI-generated examples npx vitest run --project=storybookpasses with your stories converted to tests- The Accessibility panel shows zero critical violations on your baseline components
- A local
npx chromaticrun completes and shows a baseline build in your Chromatic dashboard - Opening a test pull request triggers the GitHub Actions workflow and reports both a test status and a Chromatic review link
npm run build-storybookcompletes without errors and the static output opens correctly in a browser
If every item on that list checks out on both projects, you have a working, CI-integrated React vs Vue Storybook setup that catches logic regressions, accessibility violations, and visual drift before code reaches production.
React vs Vue Storybook Setup: Key Differences at a Glance
| Aspect | React 19.2.8 Setup | Vue 3.5.41 Setup |
|---|---|---|
| Framework package | @storybook/react-vite | @storybook/vue3-vite |
| Story syntax | JSX/TSX with typesafe CSF factories (preview feature) | Standard CSF3 objects with defineComponent typing |
| Peer dependency footprint | React + ReactDOM required | No React peer dependency since Storybook 8 |
| Docgen source | react-docgen-typescript, 25-50% faster since Storybook 8 | vue-component-meta for prop extraction |
| Vitest addon transform | Portable stories via React renderer | Portable stories via Vue 3 renderer |
| Common gotcha | Stale React peer dep from older CRA-based installs | Vue 2 projects cannot use Storybook 10 at all |
Common Pitfalls When Setting Up Storybook for React or Vue
Most Storybook 10 installs that fail hit one of these issues. Check this list before opening a GitHub issue or spending an hour in Stack Overflow.
- Running the initializer against Vue 2. Storybook 8 and every version since requires Vue 3+. If your project is still on Vue 2, migrate the framework first — there is no Storybook 10 compatibility path for Vue 2.
- Mixing CommonJS config files into an ESM-only Storybook 10 project. Because 10.0’s one breaking change is going ESM-only, any leftover
.storybook/main.jswritten withrequire()ormodule.exportswill fail. Convert toimport/exportsyntax or rename to.mjs. - Forgetting
npx playwright install chromium --with-deps. The Vitest addon runs tests in a real browser via Playwright, and skipping the browser binary install produces a cryptic “executable doesn’t exist” error the first time you run tests. - Copy-pasting React story imports into a Vue stories file. Importing from
@storybook/react-vitein a Vue project (or vice versa) compiles but produces broken or empty stories at runtime, because the renderer never receives a component it understands. - Not registering the a11y addon before writing baseline stories. Teams that add accessibility checks after dozens of components already exist often discover a backlog of violations all at once, which is demoralizing and gets deprioritized. Add the addon in Step 6, not as an afterthought six months later.
- Treating Chromatic’s free tier as unlimited. Every story variant and every viewport you test consumes a snapshot. A design system with 200 stories tested at 3 viewports burns 600 snapshots per full build — run the numbers before assuming the 5,000/month free tier covers a large team.
Troubleshooting Storybook 10 Setup Issues
Here are the most common errors teams hit during a React vs Vue Storybook setup, and the fix for each.
- “Cannot use import statement outside a module” — Your
.storybook/main.tsor a config file still uses CommonJS syntax. Convert everyrequire()/module.exportspair to ESMimport/export default. - Storybook builds but the sidebar is empty — Check the
storiesglob pattern inmain.ts. A common typo is pointing atsrc/**/*.stories.tsxin a project that also has.tsstory files, silently excluding half your components. - Vitest addon reports “No tests found” — Confirm
@storybook/addon-vitestis listed in theaddonsarray ofmain.tsand that you rannpx vitest run --project=storybook, not a barenpx vitest run, which uses your default Vitest config instead of the Storybook-generated project. - Accessibility panel shows a blank screen — Usually caused by a component that throws during render in the isolated Storybook iframe (missing context provider, missing router, etc). Check the browser console in the Storybook preview pane, not the addons panel, for the actual React or Vue error.
- Chromatic build fails with “no baseline found” — Expected on the very first run. Approve the initial build manually in the Chromatic dashboard to establish a baseline; subsequent builds will diff against it automatically.
- GitHub Actions workflow fails on
fetch-depth: 0missing — Chromatic needs full git history to detect the correct baseline commit for comparison. If you omitfetch-depth: 0in the checkout step, Chromatic cannot find an ancestor build and treats every PR as a fresh baseline. - React docgen shows wrong prop types in autodocs — Usually a stale
tsconfig.jsonreference. Confirm Storybook’s Vite config is reading the sametsconfig.jsonyour app uses, not a default one generated by the CLI. - Vue component props missing from the Controls panel — Vue’s docgen relies on
definePropswith an inline type literal or interface. Props defined via a runtime object (defineProps({ label: String })) do not get the same automatic type extraction as the TypeScript generic form used in Step 5.
Migrating an Existing React or Vue Project to Storybook 10
Not every team is starting fresh. If you already have a Storybook 7 or 8 install and are upgrading in place rather than scaffolding a new project, the path looks slightly different from Steps 1 through 5 above. Run the upgrade command from inside the existing project rather than the fresh-install initializer:
npx storybook@latest upgrade
npx storybook@latest automigrate
The automigrate command scans your existing config and story files for deprecated patterns and rewrites what it can automatically — converting .storybook/main.js to ESM syntax, flagging any leftover storiesOf calls it cannot safely auto-convert, and updating addon imports to their current package names. It will not silently fix everything: if your codebase still has MDX-based stories from a Storybook 6 or 7 install, those need manual conversion to CSF3, since the MDX story format was removed entirely and there is no automated migration path for it. Budget real time for this if your design system predates 2024 — teams migrating a component library with several hundred legacy stories commonly report the automigrate step handling 70-80% of the work automatically, with the remainder requiring hand edits to stories using APIs that no longer exist.
For Vue projects specifically, double-check your package.json after running the upgrade. Projects that were on Storybook 7 or earlier often have an explicit React dependency left over from before Storybook 8 removed that requirement for non-React renderers — the upgrade command does not remove unused dependencies on its own, so you will want to manually uninstall react and react-dom if nothing else in the Vue project actually needs them.
Advanced Tips for Scaling a React or Vue Storybook Instance
Once the base setup is stable, a few practices separate a Storybook instance that stays useful at 500 components from one that quietly gets abandoned.
First, use module automocking, a feature Storybook 10 shipped specifically to reduce test boilerplate — it auto-mocks module dependencies for stories so you are not hand-writing mock implementations for every API client a component touches. Second, split large design systems into multiple Storybook instances organized by domain (e.g., a “core” instance for buttons and inputs, a “marketing” instance for landing-page blocks) rather than one monolithic instance with thousands of stories, which slows every dev server restart. Third, set TurboSnap thresholds in Chromatic deliberately — TurboSnap only re-snapshots stories affected by a given git diff, and Chromatic’s own documentation notes it is what makes the free tier’s 5,000 snapshots stretch to roughly 25,000 story-equivalents. Fourth, if you maintain both a React and a Vue design system against the same visual language, keep story titles identical between the two (Components/Button in both) — it makes cross-framework visual parity audits in Chromatic dramatically easier to run side by side.
Fifth, use the typesafe CSF factories preview feature on the React side once your team is comfortable with the standard object-based CSF3 shown in Step 3. The factory pattern infers argument types directly from the component signature rather than requiring you to hand-write a Meta<typeof Component> annotation on every story file, which cuts boilerplate on component libraries with dozens of prop variants. It is still a preview feature as of Storybook 10.0, so pin your Storybook version deliberately if you adopt it, since preview APIs can change between minor releases without the same deprecation notice period as stable APIs. Sixth, treat the Accessibility panel’s results as a CI gate, not just a local development aid — the @storybook/addon-vitest test run can be configured to fail on accessibility violations above a chosen severity threshold, which turns a11y checks from something a developer might glance at into something a pull request cannot merge without addressing.
Seventh, resist the temptation to let stories drift away from what production components actually render. A story that hardcodes mock data no real API would ever return stops being a useful test and starts being decoration. Keep story args close to realistic API response shapes, and where a component depends on context (a theme provider, a router, an auth state), use Storybook decorators to wrap every story in that context automatically rather than duplicating provider boilerplate in each individual story file.
Storybook 10 vs Storybook 8: What Actually Changed
If your last hands-on experience with Storybook was version 8, it is worth knowing exactly what moved before you assume old habits still apply. Storybook 8, announced in March 2024, was the release that removed the storiesOf API entirely, dropped the .stories.mdx format, made the Addons API introduced in Storybook 7 mandatory, and — critically for this tutorial — removed the React peer dependency requirement for non-React renderers while adding 2-4x faster test builds and 25-50% faster React docgen. Storybook 10, which shipped in October 2025, is a smaller jump by comparison: its only documented breaking change is the move to ESM-only distribution, alongside additive features like module automocking, the typesafe CSF factories preview for React, expanded tag filtering for sidebar organization, and Svelte async component support that does not affect React or Vue projects directly.
Practically, that means a project that was already healthy on Storybook 8 or 9 should upgrade to 10 with far less friction than the 7-to-8 jump caused. The teams most likely to hit real migration pain are the ones still running Storybook 6 or earlier, since they are absorbing both the CSF3 migration from the 8.0 release and the ESM-only requirement from 10.0 in a single upgrade pass. If that describes your project, plan the upgrade as two discrete steps — get to a stable Storybook 8 or 9 first, verify everything still works, then move to 10 — rather than attempting to leap directly from a pre-2024 version straight to the current release.
Complete Working Project Structure
By the end of this tutorial, each project should match this structure:
storybook-react-demo/
├── .github/workflows/storybook.yml
├── .storybook/
│ ├── main.ts
│ └── preview.ts
├── src/
│ └── components/
│ ├── Button.tsx
│ └── Button.stories.tsx
├── package.json
└── vite.config.ts
storybook-vue-demo/
├── .github/workflows/storybook.yml
├── .storybook/
│ ├── main.ts
│ └── preview.ts
├── src/
│ └── components/
│ ├── Button.vue
│ └── Button.stories.ts
├── package.json
└── vite.config.ts
Both projects run the same npm scripts (storybook, build-storybook, and a test-storybook script wrapping the Vitest project run), which means any engineer who has set up one framework can onboard onto the other project in minutes rather than re-learning the toolchain from scratch.
When to Choose React or Vue for a New Design System
Storybook itself does not tip the scales toward either framework — the tooling parity between the two is close enough in 2026 that the decision should rest on your team’s existing skill set and your application framework choice, not on which one has a slightly nicer Storybook config. Teams already shipping on Next.js or a React Server Components architecture get more direct value from Storybook’s React-first documentation and the typesafe CSF factories preview feature. Teams on Nuxt or a Vue-first stack get a marginally lighter dependency tree (no React peer dependency to manage) and a docgen path built specifically around Vue’s Composition API typing. If you are maintaining both frameworks across different products in the same company — common after acquisitions or multi-team orgs — the side-by-side setup in this tutorial is the fastest way to keep both design systems consistent without forcing either team onto tooling they did not choose.
There is also a maintenance-cost angle worth naming directly. Running two parallel Storybook instances, two CI workflows, and two Chromatic projects doubles the surface area your platform team has to keep patched and working. That cost is worth paying when the two frameworks genuinely serve different products with different technical constraints — a marketing site on Nuxt for SEO reasons, a data-heavy internal dashboard on React for its ecosystem of table and charting libraries, for instance. It is much harder to justify when the split exists purely because two teams independently chose different frameworks for the same category of product with no real technical driver behind the divergence. In that second case, the honest recommendation is usually to consolidate onto one framework before consolidating the design system, since Storybook parity does not solve the underlying duplication of application logic, routing, and state management that a genuinely unified framework choice would.
Frequently Asked Questions
Does Storybook 10 support Vue 2?
No. Storybook dropped Vue 2 support starting with Storybook 8, and Storybook 10 continues that requirement. Vue 2 projects need to migrate to Vue 3 before adopting current Storybook versions.
Do I still need React installed to run a Vue Storybook?
No. Since Storybook 8, the React peer dependency was removed for non-React renderers, so a Vue 3 Storybook install no longer pulls in React or ReactDOM at all.
What is the difference between @storybook/addon-vitest and @storybook/experimental-addon-test?
They serve the same purpose — turning stories into Vitest component tests — but @storybook/experimental-addon-test is the earlier, explicitly experimental package whose API may still change. @storybook/addon-vitest is the stable, current package to install for Storybook 10 projects.
Is Chromatic required, or can I do visual testing without it?
Chromatic is not required — Storybook 8 also introduced a built-in Visual Tests addon for lighter-weight visual checks inside Storybook itself. Chromatic adds cross-browser cloud rendering, baseline management, and team review workflows that the built-in addon does not replicate, which is why most teams running CI pipelines still add it.
Can I run React and Vue Storybooks in the same monorepo?
Yes, as two separate Storybook instances with independent .storybook/ configs, since each framework package (@storybook/react-vite vs @storybook/vue3-vite) cannot coexist in a single Storybook config. Most monorepos run them as separate workspace packages with separate npm run storybook scripts.
Why did my Storybook 10 upgrade break with an ESM error?
Storybook 10’s only documented breaking change is that the package is now ESM-only. Any leftover CommonJS config file (typically an old .storybook/main.js using require()) needs to be rewritten with import/export syntax.
How many Chromatic snapshots does a typical design system use per month?
It depends entirely on story count and viewport count, since every story variant tested at every configured viewport counts as one snapshot. A 200-story design system tested at three viewports on every pull request can burn through the 5,000-snapshot free tier within a few weeks of active development, at which point TurboSnap’s diff-based re-snapshotting (which only re-tests stories affected by a given change) becomes essential to staying under the limit.
Does the Vitest addon replace end-to-end testing tools like Playwright or Cypress?
No. The Vitest addon tests components in isolation using their stories — it is a component-testing layer, not a replacement for end-to-end tests that exercise full user flows across multiple pages. Most teams run both: component tests via the Vitest addon for fast feedback, and a separate end-to-end suite for full-flow coverage.