{"id":13406785,"url":"https://github.com/storybookjs/react-native","last_synced_at":"2026-02-28T21:01:33.127Z","repository":{"id":38188527,"uuid":"235600443","full_name":"storybookjs/react-native","owner":"storybookjs","description":"📓 Storybook for React Native!","archived":false,"fork":false,"pushed_at":"2026-02-25T22:26:40.000Z","size":707496,"stargazers_count":1266,"open_issues_count":21,"forks_count":179,"subscribers_count":22,"default_branch":"next","last_synced_at":"2026-02-26T01:22:15.908Z","etag":null,"topics":["expo","react","react-native","storybook"],"latest_commit_sha":null,"homepage":"https://storybook.js.org","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/storybookjs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":"MAINTAINERS.md","copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"open_collective":"storybook","github":"dannyhw"}},"created_at":"2020-01-22T15:17:28.000Z","updated_at":"2026-02-25T22:26:43.000Z","dependencies_parsed_at":"2023-10-16T23:29:13.558Z","dependency_job_id":"53bac143-d1e9-431a-85f8-0f110f43c122","html_url":"https://github.com/storybookjs/react-native","commit_stats":{"total_commits":17714,"total_committers":1130,"mean_commits":"15.676106194690265","dds":0.861070339844191,"last_synced_commit":"37d653f042404bd112de99a945e8818a086fbd59"},"previous_names":[],"tags_count":261,"template":false,"template_full_name":null,"purl":"pkg:github/storybookjs/react-native","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/storybookjs%2Freact-native","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/storybookjs%2Freact-native/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/storybookjs%2Freact-native/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/storybookjs%2Freact-native/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/storybookjs","download_url":"https://codeload.github.com/storybookjs/react-native/tar.gz/refs/heads/next","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/storybookjs%2Freact-native/sbom","scorecard":{"id":854418,"data":{"date":"2025-08-11","repo":{"name":"github.com/storybookjs/react-native","commit":"456488168db2c95c3a3c6bb552de844bbde5dad2"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.6,"checks":[{"name":"Code-Review","score":2,"reason":"Found 6/29 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 23 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: topLevel 'contents' permission set to 'read': .github/workflows/docs.yml:11","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/storybookjs/react-native/docs.yml/next?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/storybookjs/react-native/docs.yml/next?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/storybookjs/react-native/docs.yml/next?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/storybookjs/react-native/docs.yml/next?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/storybookjs/react-native/test.yml/next?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/storybookjs/react-native/test.yml/next?enable=pin","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'next'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"16 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-xffm-g5w8-qvg7","Warn: Project is vulnerable to: GHSA-h5c3-5r3r-rr8q","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99","Warn: Project is vulnerable to: GHSA-m5qc-5hw7-8vg7","Warn: Project is vulnerable to: GHSA-6vfc-qv3f-vr6c","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-8cj5-5rvv-wf4v","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-3mv9-4h5g-vhg3","Warn: Project is vulnerable to: GHSA-cxrh-j4jr-qwg3","Warn: Project is vulnerable to: GHSA-4v9v-hfq4-rm2v","Warn: Project is vulnerable to: GHSA-9jgg-88mc-972h"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T23:28:16.936Z","repository_id":38188527,"created_at":"2025-08-23T23:28:16.936Z","updated_at":"2025-08-23T23:28:16.936Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29860109,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-26T08:51:08.701Z","status":"ssl_error","status_checked_at":"2026-02-26T08:50:19.607Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["expo","react","react-native","storybook"],"created_at":"2024-07-30T19:02:39.226Z","updated_at":"2026-02-28T21:01:33.095Z","avatar_url":"https://github.com/storybookjs.png","language":"TypeScript","funding_links":["https://opencollective.com/storybook","https://github.com/sponsors/dannyhw"],"categories":["TypeScript"],"sub_categories":[],"readme":"# Storybook for React Native\n\nA new docs site is being built for Storybook for React Native, you can find it at https://storybookjs.github.io/react-native/docs/intro/.\n\n\u003e [!IMPORTANT]\n\u003e This readme is for v10, for v9 docs see the [v9.1 docs](https://github.com/storybookjs/react-native/tree/v9.1.4).\n\nWith Storybook for React Native you can design and develop individual React Native components without running your app.\n\nIf you are migrating from 9 to 10 you can find the migration guide [here](https://github.com/storybookjs/react-native/blob/next/MIGRATION.md#from-version-9-to-10)\n\nFor more information about storybook visit: [storybook.js.org](https://storybook.js.org)\n\n\u003e [!NOTE]\n\u003e Make sure you align your storybook dependencies to the same major version or you will see broken behaviour.\n\n![picture of storybook](https://github.com/user-attachments/assets/cf98766d-8b90-44ab-b718-94ab16e63205)\n\n## Table of contents\n\n- 🚀 [Getting Started](#getting-started)\n- 📒 [Writing stories](#writing-stories)\n- 🔌 [Addons](#addons)\n- 📱 [Hide/Show Storybook](#hideshow-storybook)\n- ⚙️ [withStorybook wrapper](#withstorybook-wrapper)\n- 🔧 [getStorybookUI](#getstorybookui-options)\n- 🏁 [Feature Flags](#feature-flags)\n- 🧪 [Using stories in unit tests](#using-stories-in-unit-tests)\n- 🤝 [Contributing](#contributing)\n- ✨ [Examples](#examples)- [Storybook for React Native](#storybook-for-react-native)\n- 🤖 [Agent skills](#agent-skills)\n\n## Getting Started\n\n### New project\n\nThere is some project boilerplate with `@storybook/react-native` and `@storybook/addon-react-native-web` both already configured with a simple example.\n\nFor Expo you can use this [template](https://github.com/dannyhw/expo-template-storybook) with the following command\n\n```sh\n# With NPM\nnpx create-expo-app --template expo-template-storybook AwesomeStorybook\n```\n\nFor React Native CLI you can use this [template](https://github.com/dannyhw/react-native-template-storybook)\n\n```sh\nnpx @react-native-community/cli init MyApp --template react-native-template-storybook\n```\n\n### Existing project\n\nRun init to setup your project with all the dependencies and configuration files:\n\n```sh\nnpm create storybook@latest\n```\n\nThe only thing left to do is return Storybook's UI in your app entry point (such as `App.tsx`) like this:\n\n```tsx\nexport { default } from './.rnstorybook';\n```\n\nThen wrap your metro config with the withStorybook function as seen [below](#additional-steps-update-your-metro-config)\n\nIf you want to be able to swap easily between storybook and your app, have a look at this [blog post](https://dev.to/dannyhw/how-to-swap-between-react-native-storybook-and-your-app-p3o)\n\nIf you want to add everything yourself check out the manual guide [here](https://github.com/storybookjs/react-native/blob/next/MANUAL_SETUP.md).\n\n#### Additional steps: Update your metro config\n\nWe require the unstable_allowRequireContext transformer option to enable dynamic story imports based on the stories glob in `main.ts`. We can also call the storybook generate function from the metro config to automatically generate the `storybook.requires.ts` file when metro runs.\n\n**Expo**\n\nFirst create metro config file if you don't have it yet.\n\n```sh\nnpx expo customize metro.config.js\n```\n\nThen wrap your config in the withStorybook function as seen below.\n\n```js\n// metro.config.js\nconst { getDefaultConfig } = require('expo/metro-config');\nconst { withStorybook } = require('@storybook/react-native/metro/withStorybook');\n\nconst config = getDefaultConfig(__dirname);\n\n// For basic usage with all defaults, this is all you need\nmodule.exports = withStorybook(config);\n\n// Or customize the options\nmodule.exports = withStorybook(config, {\n  // When false, removes Storybook from bundle (useful for production)\n  enabled: process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === 'true',\n\n  // Path to your storybook config (default: './.rnstorybook')\n  configPath: './.rnstorybook',\n\n  // Optional websockets configuration for syncing between devices\n  // websockets: {\n  //   port: 7007,\n  //   host: 'localhost',\n  // },\n});\n```\n\n**React Native**\n\n```js\nconst { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');\nconst { withStorybook } = require('@storybook/react-native/metro/withStorybook');\n\nconst defaultConfig = getDefaultConfig(__dirname);\n\n/**\n * Metro configuration\n * https://reactnative.dev/docs/metro\n *\n * @type {import('metro-config').MetroConfig}\n */\nconst config = {};\n// set your own config here 👆\n\nconst finalConfig = mergeConfig(defaultConfig, config);\n\n// For basic usage with all defaults\nmodule.exports = withStorybook(finalConfig);\n\n// Or customize the options\nmodule.exports = withStorybook(finalConfig, {\n  // When false, removes Storybook from bundle (useful for production)\n  enabled: process.env.STORYBOOK_ENABLED === 'true',\n\n  // Path to your storybook config (default: './.rnstorybook')\n  configPath: path.resolve(__dirname, './.rnstorybook'),\n  // note that this is the default so you can the config path blank if you use .rnstorybook\n\n  // Optional websockets configuration for syncing between devices\n  // Starts a websocket server on the specified port and host on metro start\n  // websockets: {\n  //   port: 7007,\n  //   host: 'localhost',\n  // },\n});\n```\n\n#### Reanimated setup\n\nMake sure you have `react-native-reanimated` in your project and the plugin setup in your babel config.\n\n```js\n// babel.config.js\nplugins: ['react-native-reanimated/plugin'],\n```\n\n## Re.Pack setup\n\nFor projects using [Re.Pack](https://re-pack.dev/) (Rspack/Webpack) instead of Metro, see the full [Re.Pack Setup guide](https://storybookjs.github.io/react-native/docs/intro/getting-started/repack). You can also reference the [RepackStorybookStarter](https://github.com/dannyhw/RepackStorybookStarter) project.\n\n## Expo router specific setup\n\n```bash\nnpm create storybook@latest\n```\n\nchoose recommended and then native\n\n```bash\nnpx expo@latest customize metro.config.js\n```\n\ncopy the metro config\n\n```js\nconst { withStorybook } = require('@storybook/react-native/metro/withStorybook');\nmodule.exports = withStorybook(config);\n```\n\nadd storybook screen to app\n\ncreate `app/storybook.tsx`\n\n```tsx\nexport { default } from '../.rnstorybook';\n```\n\nThen add a way to navigate to your storybook route and I recommend disabling the header for the storybook route.\n\nHere's a video showing the same setup:\n\nhttps://www.youtube.com/watch?v=egBqrYg0AIg\n\n## Writing stories\n\nIn Storybook we use a syntax called CSF that looks like this:\n\n```tsx\nimport type { Meta, StoryObj } from '@storybook/react-native';\nimport { MyButton } from './Button';\n\nconst meta = {\n  component: MyButton,\n} satisfies Meta\u003ctypeof MyButton\u003e;\n\nexport default meta;\n\ntype Story = StoryObj\u003ctypeof meta\u003e;\n\nexport const Basic: Story = {\n  args: {\n    text: 'Hello World',\n    color: 'purple',\n  },\n};\n```\n\nYou should configure the path to your story files in the `main.ts` config file from the `.rnstorybook` folder.\n\n```ts\n// .rnstorybook/main.ts\nimport type { StorybookConfig } from '@storybook/react-native';\n\nconst main: StorybookConfig = {\n  stories: ['../components/**/*.stories.?(ts|tsx|js|jsx)'],\n  addons: [],\n};\n\nexport default main;\n```\n\n### Decorators and Parameters\n\nFor stories you can add decorators and parameters on the default export or on a specific story.\n\n```tsx\nimport type { Meta } from '@storybook/react';\nimport { Button } from './Button';\n\nconst meta = {\n  title: 'Button',\n  component: Button,\n  decorators: [\n    (Story) =\u003e (\n      \u003cView style={{ alignItems: 'center', justifyContent: 'center', flex: 1 }}\u003e\n        \u003cStory /\u003e\n      \u003c/View\u003e\n    ),\n  ],\n  parameters: {\n    backgrounds: {\n      values: [\n        { name: 'red', value: '#f00' },\n        { name: 'green', value: '#0f0' },\n        { name: 'blue', value: '#00f' },\n      ],\n    },\n  },\n} satisfies Meta\u003ctypeof Button\u003e;\n\nexport default meta;\n```\n\nFor global decorators and parameters, you can add them to `preview.tsx` inside your `.rnstorybook` folder.\n\n```tsx\n// .rnstorybook/preview.tsx\nimport type { Preview } from '@storybook/react-native';\nimport { withBackgrounds } from '@storybook/addon-ondevice-backgrounds';\n\nconst preview: Preview = {\n  decorators: [\n    withBackgrounds,\n    (Story) =\u003e (\n      \u003cView style={{ flex: 1, color: 'blue' }}\u003e\n        \u003cStory /\u003e\n      \u003c/View\u003e\n    ),\n  ],\n  parameters: {\n    backgrounds: {\n      default: 'plain',\n      values: [\n        { name: 'plain', value: 'white' },\n        { name: 'warm', value: 'hotpink' },\n        { name: 'cool', value: 'deepskyblue' },\n      ],\n    },\n  },\n};\n\nexport default preview;\n```\n\n## Addons\n\nThe cli will install some basic addons for you such as controls and actions.\nOndevice addons are addons that can render with the device ui that you see on the phone.\n\nCurrently, the addons available are:\n\n- [`@storybook/addon-ondevice-controls`](https://storybook.js.org/addons/@storybook/addon-ondevice-controls): adjust your components props in realtime\n- [`@storybook/addon-ondevice-actions`](https://storybook.js.org/addons/@storybook/addon-ondevice-actions): mock onPress calls with actions that will log information in the actions tab\n- [`@storybook/addon-ondevice-notes`](https://storybook.js.org/addons/@storybook/addon-ondevice-notes): Add some Markdown to your stories to help document their usage\n- [`@storybook/addon-ondevice-backgrounds`](https://storybook.js.org/addons/@storybook/addon-ondevice-backgrounds): change the background of storybook to compare the look of your component against different backgrounds\n\nInstall each one you want to use and add them to the `main.ts` addons list as follows:\n\n```ts\n// .rnstorybook/main.ts\nimport type { StorybookConfig } from '@storybook/react-native';\n\nconst main: StorybookConfig = {\n  // ... rest of config\n  addons: [\n    '@storybook/addon-ondevice-notes',\n    '@storybook/addon-ondevice-controls',\n    '@storybook/addon-ondevice-backgrounds',\n    '@storybook/addon-ondevice-actions',\n  ],\n};\n\nexport default main;\n```\n\n### Using the addons in your story\n\nFor details of each ondevice addon you can see the readme:\n\n- [actions](https://github.com/storybookjs/react-native/tree/next/packages/ondevice-actions#readme)\n- [backgrounds](https://github.com/storybookjs/react-native/tree/next/packages/ondevice-backgrounds#readme)\n- [controls](https://github.com/storybookjs/react-native/tree/next/packages/ondevice-controls#readme)\n- [notes](https://github.com/storybookjs/react-native/tree/next/packages/ondevice-notes#readme)\n\n## Hide/Show storybook\n\nIn v10, you have flexible options for integrating Storybook into your app:\n\n### Option 1: Direct export (simplest)\n\nJust export Storybook directly. Control inclusion via the metro config `enabled` flag:\n\n```tsx\n// App.tsx\nexport { default } from './.rnstorybook';\n```\n\n```js\n// metro.config.js\nmodule.exports = withStorybook(config, {\n  enabled: process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === 'true',\n});\n```\n\nWhen `enabled: false`, Metro automatically removes Storybook from your bundle.\n\n### Option 2: Conditional rendering\n\nIf you want to switch between your app and Storybook at runtime:\n\n```tsx\n// App.tsx\nimport StorybookUI from './.rnstorybook';\nimport { MyApp } from './MyApp';\n\nconst isStorybook = process.env.EXPO_PUBLIC_STORYBOOK_ENABLED === 'true';\n\nexport default function App() {\n  return isStorybook ? \u003cStorybookUI /\u003e : \u003cMyApp /\u003e;\n}\n```\n\n### Option 3: Expo Router (recommended for Expo)\n\nCreate a dedicated route for Storybook:\n\n```tsx\n// app/storybook.tsx\nexport { default } from '../.rnstorybook';\n```\n\nThen navigate to `/storybook` in your app to view stories.\n\n## withStorybook wrapper\n\n`withStorybook` is a wrapper function to extend your [Metro config](https://metrobundler.dev/docs/configuration) for Storybook. It accepts your existing Metro config and an object of options for how Storybook should be started and configured.\n\n```js\n// metro.config.js\nconst { getDefaultConfig } = require('expo/metro-config');\nconst { withStorybook } = require('@storybook/react-native/metro/withStorybook');\n\nconst defaultConfig = getDefaultConfig(__dirname);\n\nmodule.exports = withStorybook(defaultConfig, {\n  enabled: true,\n  // See API section below for available options\n});\n```\n\n### Options\n\n#### enabled\n\nType: `boolean`, default: `true`\n\nControls whether Storybook is included in your app bundle. When `true`, enables Storybook metro configuration and generates the `storybook.requires` file. When `false`, removes all Storybook code from the bundle by replacing imports with empty modules.\n\nThis is useful for conditionally including Storybook in development but excluding it from production builds:\n\n```js\n// metro.config.js\nconst { getDefaultConfig } = require('expo/metro-config');\nconst { withStorybook } = require('@storybook/react-native/metro/withStorybook');\n\nconst defaultConfig = getDefaultConfig(__dirname);\n\nmodule.exports = withStorybook(defaultConfig, {\n  enabled: process.env.STORYBOOK_ENABLED === 'true',\n  // ... other options\n});\n```\n\n#### useJs\n\nType: `boolean`, default: `false`\n\nGenerates the `.rnstorybook/storybook.requires` file in JavaScript instead of TypeScript.\n\n#### configPath\n\nType: `string`, default: `path.resolve(process.cwd(), './.rnstorybook')`\n\nThe location of your Storybook configuration directory, which includes `main.ts` and other project-related files.\n\n#### docTools\n\nType: `boolean`, default: `true`\n\nWhether to include doc tools in the storybook.requires file. Doc tools provide additional documentation features and work with `babel-plugin-react-docgen-typescript`.\n\n#### liteMode\n\nType: `boolean`, default: `false`\n\nWhether to use lite mode for Storybook. In lite mode, the default Storybook UI is mocked out so you don't need to install all its dependencies like react-native-reanimated. This is useful for reducing bundle size and dependencies. Use this when using @storybook/react-native-ui-lite instead of @storybook/react-native-ui.\n\n#### experimental_mcp\n\nType: `boolean`, default: `false`\n\nEnables an experimental MCP (Model Context Protocol) endpoint at `/mcp` on the Storybook channel server. This can be used by AI tooling to query Storybook documentation and component/story metadata. Available from v10.3 onwards.\n\nYou can enable MCP with or without websockets:\n\n- `experimental_mcp: true` starts the HTTP MCP endpoint\n- adding `websockets` also enables story selection tools over the same channel server\n\n### websockets\n\nType: `'auto' | { host: string?, port: number? }`, default: `undefined`\n\nIf specified, create a WebSocket server on startup. This allows you to sync up multiple devices to show the same story and [arg](https://storybook.js.org/docs/writing-stories/args) values connected to the story in the UI.\n\nUse `'auto'` to automatically detect your LAN IP and inject host/port into the generated `storybook.requires` file.\n\n### websockets.host\n\nType: `string`, default: `'localhost'`\n\nThe host on which to run the WebSocket, if specified.\n\n### websockets.port\n\nType: `number`, default: `7007`\n\nThe port on which to run the WebSocket, if specified.\n\n## getStorybookUI options\n\nYou can pass these parameters to getStorybookUI call in your storybook entry point:\n\n```ts\n{\n    // initialize storybook with a specific story.  eg: `mybutton--largebutton` or `{ kind: 'MyButton', name: 'LargeButton' }`\n    initialSelection?: string | Object;\n    // Custom storage to be used instead of AsyncStorage\n    storage?: {\n        getItem: (key: string) =\u003e Promise\u003cstring | null\u003e;\n        setItem: (key: string, value: string) =\u003e Promise\u003cvoid\u003e;\n    };\n    // show the onDevice UI\n    onDeviceUI?: boolean;\n    // enable websockets for the Storybook UI\n    enableWebsockets?: boolean;\n    // query params for the websocket connection\n    query?: string;\n    // host for the websocket connection\n    host?: string;\n    // port for the websocket connection\n    port?: number;\n    // use secured websockets\n    secured?: boolean;\n    // store the last selected story in the device's storage\n    shouldPersistSelection?: boolean;\n    // theme for the Storybook UI\n    theme: Partial\u003cTheme\u003e;\n}\n```\n\n## Feature Flags\n\nFeature flags let you opt into new functionality without breaking existing behavior. In the next major version, the behavior behind these flags will become the default and the flags will no longer be needed.\n\nAdd them to the `features` object in `main.ts`:\n\n```ts\n// .rnstorybook/main.ts\nimport type { StorybookConfig } from '@storybook/react-native';\n\nconst main: StorybookConfig = {\n  stories: ['../components/**/*.stories.?(ts|tsx|js|jsx)'],\n  addons: ['@storybook/addon-ondevice-controls'],\n  features: {\n    ondeviceBackgrounds: true,\n  },\n};\n\nexport default main;\n```\n\n| Flag                  | Description                                                                                                                   |\n| --------------------- | ----------------------------------------------------------------------------------------------------------------------------- |\n| `ondeviceBackgrounds` | New backgrounds API with globals-based configuration, full-screen support, and no extra package needed. Available from v10.3. |\n\nFor full documentation including configuration examples, see the [Feature Flags guide](https://storybookjs.github.io/react-native/docs/intro/configuration/feature-flags).\n\n## Using stories in unit tests\n\nStorybook provides testing utilities that allow you to reuse your stories in external test environments, such as Jest. This way you can write unit tests easier and reuse the setup which is already done in Storybook, but in your unit tests. You can find more information about it in the [portable stories section](./PORTABLE_STORIES.md).\n\n## Contributing\n\nWe welcome contributions to Storybook!\n\n- 📥 Pull requests and 🌟 Stars are always welcome.\n- Read our [contributing guide](CONTRIBUTING.md) to get started,\n  or find us on [Discord](https://discord.gg/sMFvFsG) and look for the react-native channel.\n\nLooking for a first issue to tackle?\n\n- We tag issues with [Good First Issue](https://github.com/storybookjs/react-native/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) when we think they are well suited for people who are new to the codebase or OSS in general.\n- [Talk to us](https://discord.gg/sMFvFsG), we'll find something to suits your skills and learning interest.\n\n## Examples\n\nHere are some example projects to help you get started\n\n- A mono repo setup by @axeldelafosse https://github.com/axeldelafosse/storybook-rnw-monorepo\n- Expo setup https://github.com/dannyhw/expo-storybook-starter\n- React Native CLI setup https://github.com/dannyhw/react-native-storybook-starter\n- Adding a separate entry point and dev menu item in native files for RN CLI project: https://github.com/zubko/react-native-storybook-with-dev-menu\n- Re.Pack setup https://github.com/dannyhw/RepackStorybookStarter\n- Want to showcase your own project? open a PR and add it to the list!\n\n## Agent skills\n\nThis repo includes agent skills for setting up and working with Storybook for React Native.\n\n### Skills\n\n- **writing-react-native-storybook-stories** - Guides Claude on writing stories using Component Story Format (CSF), including controls, addons, decorators, parameters, and portable stories\n- **setup-react-native-storybook** - Guides Claude through adding Storybook to your project, covering Expo, Expo Router, React Native CLI, and Re.Pack setups\n\n### Installation\n\n#### Any AI agent or IDE (universal)\n\n```sh\nnpx skills add storybookjs/react-native\n```\n\nThis works with any agent harness that supports skills (Claude Code, Cursor, Windsurf, etc.).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstorybookjs%2Freact-native","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstorybookjs%2Freact-native","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstorybookjs%2Freact-native/lists"}