Configures Metro bundler to work with Storybook in React Native. This function wraps a Metro configuration to enable Storybook usage.
Signature
function withStorybook(
config: MetroConfig,
options?: WithStorybookOptions
): MetroConfig
Parameters
The Metro bundler configuration to be modified. This should be a valid Metro config object that includes resolver, transformer, and other Metro-specific options.
Options to customize the Storybook configuration. See Metro Options for detailed options.
Returns
The modified Metro configuration with Storybook support enabled.
Usage
Basic Usage (Expo)
For basic usage with all defaults:
// metro.config.js
const { getDefaultConfig } = require('expo/metro-config');
const { withStorybook } = require('@storybook/react-native/metro/withStorybook');
const config = getDefaultConfig(__dirname);
module.exports = withStorybook(config);
With Custom Options
Configure Storybook with custom options:
// metro.config.js
const { getDefaultConfig } = require('expo/metro-config');
const { withStorybook } = require('@storybook/react-native/metro/withStorybook');
const path = require('path');
const projectRoot = __dirname;
const config = getDefaultConfig(projectRoot);
module.exports = withStorybook(config, {
configPath: path.resolve(projectRoot, './.rnstorybook'),
websockets: { port: 7007, host: 'localhost' },
useJs: false,
docTools: true,
liteMode: false,
});
Conditional Storybook (Production)
Disable Storybook in production builds:
// metro.config.js
const { getDefaultConfig } = require('expo/metro-config');
const { withStorybook } = require('@storybook/react-native/metro/withStorybook');
const config = getDefaultConfig(__dirname);
module.exports = withStorybook(config, {
enabled: process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === "true",
});
React Native CLI
// metro.config.js
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
const { withStorybook } = require('@storybook/react-native/metro/withStorybook');
const defaultConfig = getDefaultConfig(__dirname);
const config = {};
const finalConfig = mergeConfig(defaultConfig, config);
module.exports = withStorybook(finalConfig, {
enabled: process.env.STORYBOOK_ENABLED === 'true',
configPath: path.resolve(__dirname, './.rnstorybook'),
websockets: {
port: 7007,
host: 'localhost',
},
});
WebSocket Configuration
Enable WebSocket server for syncing stories across devices:
module.exports = withStorybook(config, {
websockets: {
port: 7007,
host: 'localhost',
},
});
// Or use 'auto' to automatically detect LAN IP
module.exports = withStorybook(config, {
websockets: 'auto',
});
Behavior
When enabled: true (default):
- Enables
unstable_allowRequireContext in Metro transformer
- Configures resolver for proper package exports and Storybook modules
- Automatically generates
storybook.requires.ts/js file
- Optionally starts WebSocket server for remote story control
When enabled: false:
- Removes all Storybook modules from bundle by resolving them as empty
- Replaces config folder index file with a stub
- Reduces bundle size by excluding Storybook dependencies