We're now preparing for the release of v10 and in this RC we have most if not all of the changes ready
Version 10 brings Storybook React Native in sync with Storybook core v10 and introduces improved Metro configuration.
Update your metro config
The withStorybook metro wrapper has been significantly simplified in v10. The key changes are:
- Import path unified - In v9,
withStorybookConfig(frommetro/withStorybookConfig) was a preview of the simplified API. In v10, this is now the standard behavior when importingwithStorybookfrommetro/withStorybook onDisabledRemoveStorybookis removed - Whenenabled: false, Storybook is automatically removed from the bundle (no separate flag needed)- Simpler defaults - Works out of the box with sensible defaults
Before (v9):
When using withStorybook with the old API:
const withStorybook = require('@storybook/react-native/metro/withStorybook');
module.exports = withStorybook(defaultConfig, {
enabled: process.env.STORYBOOK_ENABLED === 'true',
onDisabledRemoveStorybook: true, // This option no longer exists in v10
});After (v10):
const { withStorybook } = require('@storybook/react-native/metro/withStorybook');
// Basic usage - works out of the box with defaults
module.exports = withStorybook(defaultConfig);
// Or with options
module.exports = withStorybook(defaultConfig, {
// When false, automatically removes Storybook from bundle
enabled: process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === 'true',
});The updated config will automatically stub out the rnstorybook config folder when enabled is set to false as well as the storybook packages.
This makes it so that you don't need to wrap your imports of storybook with conditionals to avoid crashing the app.
for example:
// App.tsx
let AppEntryPoint = App;
if (process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === 'true') {
// Conditional import to avoid bundling Storybook in production
AppEntryPoint = require('./.rnstorybook').default;
}
export default AppEntryPoint;
could now just be imported in a more natural way like this:
import StorybookUI from './.rnstorybook';
const isStorybook = process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === 'true';
export default function App() {
return isStorybook ? <StorybookUI /> : <AppComponent />;
}