React Native Storybook 8
React Native is back in the fold!
Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation. Not only is it ubiquitous for building web UX, but it is the only component workshop for React Native, used by Amazon, Shopify, Brex, Wealthsimple, Kraken, and many more mobile teams around the globe.
For the past half-decade we worked hard to close the gap between React Native Storybook and the fast-moving Web version. Today I’m excited to announce that we’ve finally achieved this major milestone. Storybook for React Native 8.3 is the release that unifies the two projects.
It includes:
- 🤝 Unified release schedule with web
- 📱 Brand new mobile UI
- ↔️ New widescreen layout
- ⚙️ Simplified Metro config
- 🔁 Improved hot-reloading
- 🏆 Stable React Native Web support
Unified release schedule with web
Before we get into the feature improvements in 8.3, why is this release so important? This is the culmination of four years of work by React Native (RN) Storybook’s lead maintainer, Danny Williams.
Danny started maintaining React Native Storybook in 2020. He sacrificed his nights and weekends for years, first to keep the lights on, and then to pursue the herculean task of reuniting RN Storybook with the Web version.
During this time, React Native Storybook trailed Web Storybook by a major version. In a fast-moving project like Storybook, this means RN users were getting a worse experience than web users, and teams that were using both RN and Web were held back by a version.
No more! RN Storybook 8.3 includes all of Web’s key core features. The codebase allows for sharing between RN and Web, which means our team can commit to ensuring that Web major releases don’t break RN in the future. This is an epic milestone for the project.
Brand new mobile UI
The most prominent change in RN Storybook 8 is a brand new UI, a complete overhaul that optimizes Storybook’s UI for mobile. Now, both the navigation sidebar and addon panel spring up from the bottom of the page, making them easy to trigger with your thumb on a phone. Unlike the previous version, these panels co-exist cleanly with the main “Canvas” area of Storybook:
This has been a huge improvement in Storybook for Web since it was introduced in Storybook 8, but it’s even more significant for React Native, which lives entirely on your mobile device.
New widescreen layout
React Native is also increasingly used for tablet, desktop, and web applications. To keep up, we’ve introduced a new widescreen layout that matches Storybook for Web’s desktop layout.
Simplified Metro config
To help configure Storybook more cleanly, we’ve introduced the new withStorybook
wrapper for your Metro config:
// metro.config.js
const { getDefaultConfig } = require("expo/metro-config");
const withStorybook = require("@storybook/react-native/metro/withStorybook");
const defaultConfig = getDefaultConfig(__dirname);
module.exports = withStorybook(defaultConfig);
The wrapper also accepts an options object to customize the behavior. For example, if you want to start a websocket server alongside your RN Storybook so that it can be remotely controlled (e.g. by a Storybook web UI, VSCode extension, or test script):
// metro.config.js
const { getDefaultConfig } = require("expo/metro-config");
const withStorybook = require("@storybook/react-native/metro/withStorybook");
const defaultConfig = getDefaultConfig(__dirname);
module.exports = withStorybook(defaultConfig, {
websockets: {
port: 7007,
host: 'localhost',
},
});
You can also use the options to specify an alternative configuration directory or to disable Storybook entirely based on environment variable. For more info see the docs.
Improved hot reloading
In older versions, RN Storybook would hot reload existing stories and supported adding/removing stories from existing story files. However, adding and removing story files required a restart.
Now, thanks to Metro improvements, you can now add and remove story files that match your stories
globs in .storybook/main.js
and Storybook will pick those up automatically.
Note that updating main.js
with new file globs will still require running storybook-generate
or restarting Metro.
React Native Web is stable
To celebrate our React Native 8 release, we’ve also fixed a variety of bugs and compatibility issues in React Native Web (RNW) Storybook, our web-based React Native component workshop.
If you’re not already familiar with RNW Storybook, it is a great complement to Storybook for RN. While RN runs as a native app on your device, React Native Web runs in React DOM inside the web browser. Thus, it is fully compatible with Web Storybook including:
- 📚 Storybook Docs (autodocs + MDX)
- 🧪 Storybook Test Runner and other testing tools
- 🧩 Most of Storybook’s addons, including A11y, i18n, and more
- 👁️ Visual testing tools like Chromatic
Perhaps most importantly, it gives you a nice web-browsable collection of stories that is easily accessed from the web.
Of course, Web emulation is only an approximation, and certain RN components / features / interactions are only available natively on the device.
But RN Storybook and RNW Storybook can co-exist in a project, so you can have the best of both worlds! Please see the documentation for how to set up Storybook RNW in your project.
Try it today
If you’re starting a new RN project, check out the Storybook for React Native tutorial, which has been updated to v8!
If you’re upgrading an existing RN project, first update all storybook dependencies to 8.3.1 or newer.
// package.json
{
"devDependencies": {
"@storybook/react-native": "^8.3.1",
"@storybook/react": "^8.3.1",
"@storybook/addon-ondevice-controls": "^8.3.1",
"@storybook/addon-ondevice-actions": "^8.3.1",
"@storybook/addon-ondevice-backgrounds": "^8.3.1",
"@storybook/addon-ondevice-notes": "^8.3.1"
}
}
Then add several new dependencies to your project, which are required by the updated UI. If you're using Expo, expo install
is the safest way to get versions that are compatible with your setup:
npx expo install react-native-reanimated react-native-gesture-handler @gorhom/bottom-sheet react-native-svg
If you're using RN CLI, you'll need to make sure that you use versions that are compatible with your version of React Native:
npm install react-native-reanimated react-native-gesture-handler @gorhom/bottom-sheet react-native-svg
Next, regenerate your .storybook/storybook.requires.ts
file by running yarn storybook-generate
. You should see a new updateView
function in the file.
Finally, apply the new Metro config wrapper to apply Storybook settings.
// metro.config.js
const withStorybook = require('@storybook/react-native/metro/withStorybook');
const config = /* existing configuration */;
module.exports = withStorybook(config);
We’ve documented the upgrade process for this version and previous versions in RN Storybook’s MIGRATION.md.
What’s next?
We’re excited to finally be up to date with Storybook for Web. After the 8.3 release we are planning a variety of improvements:
- Bringing controls on native inline with the web
- Testing integrations and utilities
- 🤔… Let us know your suggestions!
Most importantly, we plan to keep Storybook for React Native in sync with the Web side of Storybook.
Thanks for reading, if you have feedback please let us know so we can continue to improve. To get in touch drop by in the Discord or create a discussion on GitHub. To keep up with React Native Storybook you can follow Danny_H_W on Twitter.