Skip to main content
The Storybook UI can be configured through the getStorybookUI method, which provides options for customizing the on-device interface, WebSocket connections, and story persistence.

Basic Usage

index.tsx
import { start } from '@storybook/react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';

const view = start({
  annotations,
  storyEntries,
});

const StorybookUI = view.getStorybookUI({
  storage: {
    getItem: AsyncStorage.getItem,
    setItem: AsyncStorage.setItem,
  },
});

export default StorybookUI;

Configuration Options

interface Params {
  onDeviceUI?: boolean;
  hasStoryWrapper?: boolean;
  enableWebsockets?: boolean;
  query?: string;
  host?: string;
  port?: number;
  secured?: boolean;
  initialSelection?: InitialSelection;
  shouldPersistSelection?: boolean;
  theme?: ThemePartial;
  storage?: Storage;
  CustomUIComponent?: SBUI;
}

Options

onDeviceUI
boolean
default:"true"
Whether to show the on-device Storybook UI.When false, only renders the story component without navigation controls.
view.getStorybookUI({
  onDeviceUI: false,
});
Set to false if you want to render stories in your own custom navigation.
hasStoryWrapper
boolean
default:"true"
Set as false to disable the wrapper around the story view.
view.getStorybookUI({
  hasStoryWrapper: false,
});
This option may be removed in the future for a better solution.
enableWebsockets
boolean
default:"false"
Enable WebSockets for the Storybook server to remotely control Storybook.This allows you to control the on-device Storybook from a browser or external tools.
view.getStorybookUI({
  enableWebsockets: true,
  host: 'localhost',
  port: 7007,
});
See WebSocket Configuration for details.
query
string
default:"undefined"
Optional query string to append to the WebSocket connection URL.
view.getStorybookUI({
  enableWebsockets: true,
  query: 'token=abc123',
});
host
string
default:"Platform dependent"
The host for the WebSocket server.
  • Android emulator: Defaults to 10.0.2.2 (host machine from emulator)
  • iOS simulator & physical devices: Defaults to localhost
view.getStorybookUI({
  enableWebsockets: true,
  host: '192.168.1.100', // Your local IP
});
If you configured WebSockets in Metro config, the host is automatically injected via globalThis.STORYBOOK_WEBSOCKET.host.
port
number
default:"7007"
The port for the WebSocket server.
view.getStorybookUI({
  enableWebsockets: true,
  port: 7007,
});
If you configured WebSockets in Metro config, the port is automatically injected via globalThis.STORYBOOK_WEBSOCKET.port.
secured
boolean
default:"false"
Whether to use secure WebSocket connections (wss:// instead of ws://).
view.getStorybookUI({
  enableWebsockets: true,
  secured: true,
});
initialSelection
InitialSelection
default:"undefined"
The initial story to display when Storybook loads.Can be a story ID string or an object with kind and name.
// Using story ID
view.getStorybookUI({
  initialSelection: 'button--primary',
});

// Using kind and name
view.getStorybookUI({
  initialSelection: {
    kind: 'Button',
    name: 'Primary',
  },
});
The kind is the default export name or storiesOf("name") name. The name is the named export or .add("name") name.
shouldPersistSelection
boolean
default:"true"
Whether to persist story selection between app restarts.When true, requires the storage option to be configured.
view.getStorybookUI({
  shouldPersistSelection: true,
  storage: {
    getItem: AsyncStorage.getItem,
    setItem: AsyncStorage.setItem,
  },
});
theme
ThemePartial
default:"System theme"
Custom theme object to override the default Storybook theme.The theme automatically switches between light and dark mode based on the device’s color scheme.
view.getStorybookUI({
  theme: {
    backgroundColor: '#1a1a1a',
    primaryColor: '#ff4785',
  },
});
See @storybook/react-native-theming for available theme properties.
storage
Storage
default:"undefined"
Storage implementation for persisting story selection.Required if shouldPersistSelection is true.
interface Storage {
  getItem: (key: string) => Promise<string | null>;
  setItem: (key: string, value: string) => Promise<void>;
}
import AsyncStorage from '@react-native-async-storage/async-storage';

view.getStorybookUI({
  storage: {
    getItem: AsyncStorage.getItem,
    setItem: AsyncStorage.setItem,
  },
});
You’ll see a warning in the console if shouldPersistSelection is true but storage is not provided.
CustomUIComponent
SBUI
default:"undefined"
Custom UI component to use instead of the default Storybook UI.This allows you to create a completely custom interface for navigating stories.
const CustomUI = ({ story, storyHash, setStory, children, theme }) => (
  <View>
    <MyCustomNavigation stories={storyHash} onSelect={setStory} />
    {children}
  </View>
);

view.getStorybookUI({
  CustomUIComponent: CustomUI,
});
The children prop contains the rendered story component.

Examples

Complete Configuration

index.tsx
import { start } from '@storybook/react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';

const view = start({
  annotations,
  storyEntries,
});

const StorybookUI = view.getStorybookUI({
  onDeviceUI: true,
  enableWebsockets: true,
  host: 'localhost',
  port: 7007,
  shouldPersistSelection: true,
  storage: {
    getItem: AsyncStorage.getItem,
    setItem: AsyncStorage.setItem,
  },
  initialSelection: 'button--primary',
  theme: {
    backgroundColor: '#1a1a1a',
  },
});

export default StorybookUI;

Headless Mode (No UI)

const StorybookUI = view.getStorybookUI({
  onDeviceUI: false,
  hasStoryWrapper: false,
  enableWebsockets: true,
});

Custom Theme

import { darkTheme } from '@storybook/react-native';

const StorybookUI = view.getStorybookUI({
  theme: {
    ...darkTheme,
    primaryColor: '#ff4785',
    backgroundColor: '#000000',
  },
  storage: {
    getItem: AsyncStorage.getItem,
    setItem: AsyncStorage.setItem,
  },
});

Deep Linking

Storybook automatically handles deep links to specific stories:
// Deep link URL format
YOUR_APP_SCHEME://storybook?STORYBOOK_STORY_ID=button--primary
When a deep link is received, Storybook will navigate to the specified story if it exists in your story index.
Deep linking works automatically. No additional configuration is needed beyond setting up your app’s URL scheme.

Storage Key

Storybook stores the last opened story ID using the key:
const RN_STORYBOOK_STORAGE_KEY = 'lastOpenedStory';
This value is stored in the provided storage implementation (typically AsyncStorage).

Build docs developers (and LLMs) love