Storybook for React Native Web
Storybook for React Native Web is a framework that makes it easy to develop and test UI components in isolation for React Native applications. It uses Vite to build your components for web browsers. The framework includes:
- ⚛️ React Native components
- 🧑💻 Shareable on the web
- 🪄 Zero config
- 💫 and more!
In addition to React Native Web, Storybook supports on-device React Native development. If you're unsure what's right for you, read our comparison.
Requirements
- React-Native ≥ 0.72
- React-Native-Web ≥ 0.19
- Storybook ≥ 8.5
- Vite ≥ 5.0
Getting started
In a project without Storybook
Follow the prompts after running this command in your React Native project's root directory:
npm create storybook@latest
More on getting started with Storybook.
In a project with Storybook addon-react-native-web
The React Native Web addon was a Webpack-based precursor to the React Native Web Vite framework (i.e., @storybook/react-native-web-vite
). If you're using the addon, you should migrate to the framework, which is faster, more stable, maintained, and better documented. To do so, follow the steps below.
Run the following command to upgrade Storybook to the latest version:
npx storybook@latest upgrade
This framework is designed to work with Storybook 8.5 and above for the best experience. We won't be able to provide support if you're using an older Storybook version.
Install the framework and its peer dependencies:
npm install --save-dev @storybook/react-native-web-vite vite
Update your .storybook/main.js|ts
to change the framework property and remove the @storybook/addon-react-native-web
addon:
export default {
addons: [
'@storybook/addon-react-native-web', // 👈 Remove the addon
],
// Replace @storybook/react-webpack5 with the Vite framework
framework: '@storybook/react-native-web-vite',
};
Finally, remove the addon and similar packages (i.e., @storybook/react-webpack5
and @storybook/addon-react-native-web
) from your project.
In a project with Storybook react-native
Storybook for React Native is a framework that runs in a simulator or on your mobile device. It's possible to run React Native Web alongside React Native, but we are still working on a seamless integration. In the meantime, we recommend running one or the other. If you need help figuring out what's right for you, read our comparison.
Run the Setup Wizard
If all goes well, you should see a setup wizard that will help you get started with Storybook. The wizard will introduce you to the main concepts and features, including how the UI is organized, how to write your first story, and how to test your components' response to various inputs utilizing controls.
If you skipped the wizard, you can always run it again by adding the ?path=/onboarding
query parameter to the URL of your Storybook instance, provided that the example stories are still available.
React Native vs React Native Web
If you’re building React Native (RN) components, Storybook has two options: Native and Web.
Both options provide a catalog of your stories that hot refreshes as you edit the code in your favorite editor. However, their implementations are quite different:
- Native - Runs inside your React Native application. It’s high-fidelity but has a limited feature set.
- Web - Displays your React Native components in the browser. It’s based on Storybook for Web, which is feature-rich and mature.
So, which option is right for you?
Native. You should choose this option if you want:
- Native features - Your components rely on device-specific features like native modules. It runs in your actual application, in-simulator, or on-device and provides full fidelity. The web version uses
react-native-web
, which works for most components but has limitations. - Mobile publication - You want to share your Storybook on-device as part of a test build or embedded inside your application.
Web. You should choose this option if you want:
- Sharing - Publish to the web and share with your team or publicly.
- Documentation - Auto-generated component docs or rich markdown docs in MDX.
- Testing - Component, visual, and a11y tests for your components.
- Addons - 500+ addons that improve development, documentation, testing, and integration with other tools.
Both. It’s also possible to use both options together. However, this increases Storybook’s install footprint and requires more work to configure. Therefore, we recommend choosing one option to start and extending it once you have something working.
API
Options
You can pass an options object for additional configuration if needed:
import type { StorybookConfig } from '@storybook/react-native-web-vite';
const config: StorybookConfig = {
framework: {
name: '@storybook/react-native-web-vite',
options: {
// You should apply babel plugins and presets here for your project that you want to apply to your code
// for example put the reanimated preset here if you are using reanimated
// or the nativewind jsxImportSource for example
pluginReactOptions: {
jsxRuntime: 'automatic' | 'classic', // default: 'automatic'
jsxImportSource: string, // default: 'react'
babel:{
plugins: Array<string | [string, any]>,
presets: Array<string | [string, any]>,
// ... other compatible babel options
}
include: Array<string|RegExp>,
exclude: Array<string|RegExp>,
// ... other compatible @vitejs/plugin-react options
}
// these options are used to configure transpilation of node_modules via babel
// in most cases, you don't need to configure these options, but they are available if you need them
pluginBabelOptions: {
include: Array<string|RegExp>, // default: [/node_modules\/(react-native|@react-native)/]
exclude: Array<string|RegExp>, // default: undefined
presets: Array<string|[string, any]>,
plugins: Array<string|[string, any]>,
presetReact?: {
runtime?: 'automatic' | 'classic'; // default: 'automatic'
importSource?: string; // default: 'react'
};
// ... other compatible vite-plugin-babel options
}
},
},
};
export default config;
Example configuration for reanimated
const main: StorybookConfig = {
// ... rest of config
framework: {
name: "@storybook/react-native-web-vite",
options: {
pluginReactOptions: {
babel: {
plugins: [
"@babel/plugin-proposal-export-namespace-from",
"react-native-reanimated/plugin",
],
},
},
},
},
// ... rest of config
}
Example configuration for nativewind
const main: StorybookConfig = {
// ... rest of config
framework: {
name: "@storybook/react-native-web-vite",
options: {
pluginReactOptions: {
jsxImportSource: "nativewind",
},
},
},
}
builder
Type: Record<string, any>
Configure options for the framework's builder. For this framework, available options can be found in the Vite builder docs.