<p>Storybook 10 contains one breaking change: it’s ESM-only. By removing CommonJS from published code, we’ve simplified Storybook and reduced its install size by 29% while simultaneously un-minifying our distribution for easier debugging.</p><p>Storybook 10 also includes key improvements to level up your UI development, documentation, and testing workflows:</p><ul><li>🧩 Module automocking for easier testing</li><li>🏭 Typesafe CSF factories Preview for React</li><li>💫 UI editing and sharing optimizations</li><li>🏷️ Tag filtering exclusion for sidebar management</li><li>🔀 Svelte async components, Next 16, Vitest 4, and more</li></ul><p>And finally, while you’re here, we’re also excited to share some experimental work for feedback:</p><ul><li>🧪 Test syntax for familiarity and reduced sidebar clutter</li><li>⚛️ Component testing RSCs</li></ul><h2 id="esm-only">ESM-only</h2><p>ESM-only is the main breaking change in Storybook 10. It reduces install size by 29% on top of the 50% savings we released in Storybook 9.</p><p>More importantly, it helps push the Javascript community forward towards a cleaner, simpler future. The ecosystem is healing. We are so excited about this change, we think it deserves its own post.</p><p>ESM-only requires a modern Node that supports ESM require (20.16+, 22.19+, or 24+).</p>
sb.mock is inspired by vi.mock, but it’s simpler, compatible with both Vite and Webpack builders, and available in both development and static production builds. Read all about it in our feature announcement post.</p>
// CSF 3
import type { Meta, StoryObj } from '@storybook/nextjs-vite';
import Button from './Button';
const meta = { component: Button } satisfies Meta<typeof Button>; export default meta;
type Story = StoryObj<typeof meta>;
export const Primary: Story = { args: { label: ‘Button’, primary: true } };
// CSF Factories - Less boilerplate and no type assignments! 🎉 import preview from ‘../.storybook/preview’; import Button from ‘./Button’;
const meta = preview.meta({ component: Button });
export const Primary = meta.story({
args: { label: ‘Button’, primary: true }
});
</code></pre><p>With Storybook 10 we are promoting CSF Factories from Experimental to Preview status, which means we don’t anticipate any significant changes when we make Factories the default in Storybook 11 next Spring. There are codemods to automatically upgrade your existing stories, but you are not obligated to upgrade. Older versions of CSF are still supported and will be for the foreseeable future.</p><p>CSF Factories are available for React only, and we expect to release Vue, Angular, and Web Components factory support in 10.x.</p><h2 id="ui-editing-and-sharing-optimizations">UI editing and sharing optimizations</h2><p>At Storybook, we sweat the details, continuously refining our UI to make you more productive. Storybook 10 includes another round of optimizations for easier story editing and sharing.</p><p>Want to see how that component looks on your mobile phone? The sharing menu now has a QR code for easy access:</p>

// Button.stories.ts
export const GlassMode: Story = {
args: { glass: true },
tags: [‘experimental’],
};
</code></pre><p>In Storybook 8.5, we added a filtering UI to filter the the sidebar down to tags matching a particular tag. For example, if you wanted to only show stories with the experimental tag, you could select the experimental tag in the UI:</p>
experimental tag, you can do that too:</p>
// .storybook/main.ts
const config: StorybookConfig = {
tags: {
experimental: { defaultFilterSelection: ‘exclude’ },
},
};
</code></pre><p>To learn all about Storybook tags, please see the documentation.</p><h2 id="svelte-async-components-and-state-mocking">Svelte async components and state mocking</h2><p>Thanks to our vibrant collaboration with the Svelte community, Storybook for Svelte keeps getting better. In Storybook 10, we’ve added support for async components, Svelte’s latest innovation. We’ve also added mocking support forapp/state, closing a long-standing gap in our SvelteKit integration. If you’re a Svelte user and haven’t tried Storybook in awhile, we highly recommend giving it another try!</p><h2 id="next-16-vitest-4-and-more">Next 16, Vitest 4, and more!</h2><p>Every Storybook release is a chance to upgrade with ecosystem. Storybook 10 adds support for Next 16 and Vitest 4, two of the biggest releases this Fall. We’ve done this while preserving support for older versions.</p><h2 id="try-storybook-10-today">Try Storybook 10 today</h2><p>Try Storybook 10 in a new project:</p><pre>npm create storybook@latest
</pre><p>In an existing Storybook project, use our automated migration wizard to help you upgrade:</p><pre>npx storybook@latest upgrade
</pre><p>We also provide a migration guide to help fill in the gaps.</p><h2 id="what%E2%80%99s-next-test-syntax-rsc-testing">What’s next? Test syntax, RSC testing</h2><p>Every release we announce what’s next and point at our roadmap. This time we’re doing things a little different and we have a bunch of stuff cooking that you can try today and help us shape the future of UI development together.</p><h3 id="experimental-test-syntax">Experimental test syntax</h3><p>Building on the CSF Factories syntax and Tag exclusion filtering exclusion described above, we’ve made it possible to write tests in a familiar syntax and then easily exclude them from the sidebar to remove clutter for non-technical collaborators:</p><pre>// Button.stories.ts
import preview from '../.storybook/preview';
import { Button } from ‘./Button’;
const meta = preview.meta({ component: Button });
export const Disabled = meta.story({ args: { disabled: true } });
// 🆕 .test method: Attach tests to a story! // The test function can run the same code as the play function Disabled.test(‘should be disabled’, async ({ canvas, userEvent, args }) => { const button = await canvas.findByRole(‘button’); await userEvent.click(button);
await expect(button).toBeDisabled();
await expect(args.onClick).not.toHaveBeenCalled();
});
</code></pre><p>For more information, see our RFC and join our early access program to discuss potential improvements.</p><h3 id="experimental-rsc-component-testing">Experimental RSC component testing</h3><p>Finally, we are collaborating with the entire React ecosystem (React core, Next, Testing Library, Vite, and Vitest) to solve component testing for React Server Components (RSCs).</p><p>Until now, RSCs have been exclusively tested end-to-end (E2E), since they span both the client and server. However, it is challenging to scale E2E to a large number of tests due to performance and flake. Comparatively, component tests are fast, highly controlled, and low-flake.</p>
✂️ ESM-only (the only breaking change!) 🧩 Module automocking for easier testing 🏭 Typesafe CSF factories Preview for React 💫 UI editing and sharing optimizations 🏷️ Tag filtering exclusion for sidebar management 🔀 Svelte async component support</p>— Storybook (@storybook.js.org) 2025-11-04T19:02:28.200Z</blockquote></figure>