What's new?
Performance Improvements
First, Storybook version 8 introduces significant performance improvements. If you have a React project, this upgrade reduces your Storybook start time by up to 20%. For Webpack projects, Storybook 8 uses Speedy Web Compiler (SWC) as the default compiler for new projects, speeding up the load time for stories.
I recently upgraded a Next.js project with 70+ components from Storybook version 6.5 to version 8, reducing its start time by 30%. Here are the before and after stats.
Storybook V6 | Storybook V8 | |
---|---|---|
Manager | 27 s | 709 ms |
Preview | 34 s | 17 s |
In addition to the performance improvement, Storybook version 8 also introduces some exciting updates, such as a better mobile user experience and a robust add-on that lets you run visual tests of your stories locally without the need to commit changes.
Out of all these new updates, the one that excited me the most was the support for the React Server Component (RSC). While it's still experimental and limited to Next.js projects, the RSC support opens the opportunity to develop and test server components in isolation.
What changed?
The Approach of Writing Stories
Some changes will require your attention. The most noticeable one is about how to write stories.
If your project uses the older storiesOf syntax to write stories, you would need to rewrite them with the Component Story Format (CSF) since the storiesOf API is now removed from Storybook version 8.
"What is Component Story Format (CSF)?" you ask.
storiesOf is the original API to create stories in Storybook. Storybook introduced the Component Story Format (CSF) in Storybook Version 5. Since then, Storybook has moved to a more modular approach to defining stories with CSF.
With the storiesOf syntax, you create stories for a Button component like the following:
import { storiesOf } from '@storybook/react';
import { Button } from "./Button";
storiesOf('Components/Button', module)
.add('Primary', () => <Button label="submit" />)
.add('Secondary', () => <Button label="submit", variant="secondary" />)
In CSF, stories and component metadata are essentially ES module exports. Every component story file includes the following:
- a required default export that configures component metadata. For example, this export determines how the component is categorized.
- multiple named exports that represent different variants of the component.
We write stories using the CSF3 syntax as follows:
import { Button } from "./Button";
export default meta {
title: 'Components/Button',
component: Button,
args: {
variant: 'primary',
label: 'submit'
}
};
// can be empty since default props are provided from the default export
export const Primary: Story = {};
export const Secondary: Story = {
args: {
variant: 'secondary',
}
}
If you write stories using the storiesOf API, you can run this migration script to convert them to the CSF format.
npx storybook@latest migrate storiesof-to-csf --glob="**/*.stories.tsx" --parser=tsx
There is also a migration script if you're writing stories in CSF format and want to start using the latest CSF3 format.
npx storybook@latest migrate csf-2-to-3 --glob="**/*.stories.tsx" --parser=tsx
I converted 78 stories written with CSF2 to the CSF3 format within seconds.
Moving Away from Using MDX for Both Documentation and Defining Stories
Another change that should get your attention is that Storybook version 8 no longer supports using .stories.mdx files for mixing stories with markdown documentation.
Storybook provides migration scripts to assist in moving to the new format.
npx storybook@latest migrate mdx-to-csf --glob "**/*.stories.mdx"
Moving Away from Storyshot Testing
Snapshot is a Storybook add-on that automatically captures a code snapshot of every story with Jest. This add-on is removed in Storybook 8, and this is a migration guide for storyshots.
More changes?
I have discussed the major changes focused on the React projects so far. You can find all the changes from the Storybook 8 Changelog here.
Practical Steps to Plan for the Migration
Thinking about migration can be overwhelming. It might be tempting to delay the upgrade until it becomes critical. However, starting to plan and test the migration early could help you avoid complications before it's too late. It's also beneficial to familiarize your team with the new system and detect compatibility issues early on.
Taking a proactive approach makes the migration process smoother and allows you to take advantage of the latest updates to improve your project's performance and user experience.
So, how do we get started?
Proof of Concept: Experiment with the Migration
First things first, Storybook provides excellent migration guides you should use as a point of reference:
Following along with the official migration guide, we start by branching on the UI project and run this Storybook auto-upgrade script at the root of the project.
npx storybook@latest upgrade
Running this script will upgrade your Storybook dependencies to the latest version and run a collection of auto-migration checks. This script does its best to help you find solutions to unblock the migration if it finds any incompatibility issues.
As shown in the following screenshots, when I ran the auto-upgrade script on a Storybook 6 UI project, the script checked for potential migration blockers and instructed me to fix those issues.
The auto-migration script can fix some of these issues.
When the process is completed, the auto-migration script summarizes what is done automatically and what steps require manual migration.
If your project uses a newer version of Storybook, this is probably the only step you need to complete the migration!
Thoroughly Testing the Migration
But that is not it! While everything looks fine on the migration, we must thoroughly test the Storybook UI to ensure everything is running smoothly in the new version.
Watch for any hiccups with custom configurations, especially your typescript configs and add-on configurations. Some community add-ons might not play nice with Storybook version 8, so be prepared to find alternatives or workarounds.
For instance, the auto-migration script partially fixed an issue caused by a community add-on during my migration, but I still saw an error related to that add-on, which failed the Storybook build. In this case, I had to remove the community add-on from the main.js file to make the Storybook build work again.
My migration is working fine. What is the next step?
Now that we've experimented with the Storybook 8 migration and everything looks fine, what's the next step?
First, it's critical to stay on top of your team's feedback. This migration may also require upgrading other dependencies, such as the Node.js version, and changing things like how to test stories and how stories are written moving forward. It helps communicate alignments by providing this experimental migration as a Proof of Concept, collecting feedback from across the team, and weighing in on the long-term benefits and impact of such changes.
Next, ensure your team is educated on writing stories with the new syntax. While the migration script can do magic to transform your existing stories to the up-to-date CSF syntax, remember to provide resources for your team to follow on the changes. You can also streamline this process by adding a story generator script using templates such as PlopJS or schematics to familiarize developers with the new CSF syntax.