This guide is a written version of a video I recently made and will show you how to get started with react native storybook on an existing project. This assumes that you already have a react native project to start with. For my purposes I'm starting with the expo typescript template but you can use react native cli if you prefer.
Heres the video if you want to watch me do it and talk through the process
The first thing you'll want to do is open the terminal in your project folder and run
npx sb@latest init --type react_native
This will create all the files and install all the packages you need to get started.
As you can see from the message here the setup isn't fully automated and the next step is to get storybook to render by replacing your entry point with the Storybook component.
Lets now take a look at what got added to our project
There were some new packages installed, two new scripts and a .storybook
folder which contains all the storybook config. The .storybook/index.js
file exports the Storybook component which we need to render to get storybook working.
Now in your editor open up App.tsx
(or js/jsx) or wherever your app entrypoint and import and export the component .storybook/index.js
like you would normally export the App component. For now you can comment out your existing default export but later you can setup a way to swap between storybook and your app.
import StorybookUI from "./.storybook";
export default StorybookUI;
Next we'll make one quick change to our metro config.
If you're on expo you'll need to generate that file with
npx expo customize metro.config.js
Then in that file add sb modern to the start of the resolver.resolverMainFields array. In expos generated file you can do it like this.
// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require("expo/metro-config");
/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);
config.resolver.resolverMainFields.unshift("sbmodern");
module.exports = config;
note: you'll be happy to know sbmodern won't be needed in v7 of storybook
Now you can run yarn ios
or yarn android
and when the app opens up you should see the storybook UI.
Why aren't my new stories showing up?
When you add new stories you might notice that they don't immediately show up, thats because currently you need to run yarn storybook-generate
each time you add a new story.
I like to add it to the start command like this so that I never forget
"start": "yarn storybook-generate && expo start",
This is needed because until recently react native didn't support dynamic imports and we generate a list of story imports based on your main.js
config. You can see this in the storybook.requires.js
file. This is something that we'll be changing in the future but for now make sure that you run storybook-generate
whenever your new stories aren't showing up.
Thats it folks
Thanks for reading this post, if you're wondering where to go from here I recommend taking a look at some of my other posts or following the tutorial I wrote for react native storybook.
You can find me on twitter here @Danny_H_W
You can find my work on github here dannyhw
My DM's are open on twitter in case you want to get in touch.
Top comments (5)
@dannyhw
Do you think we need to add a section
"Run storybook with Expo development build"
Correct me if i am wrong, but your example only work with Expo Go 😅
because right now (with Expo SDK 49) we have the choice to switch between
Expo Go
anddevelopment build
Theres no difference with how you run this with expo dev clients. You just change the start command. Everything that works on expo go should work with a dev client as far as I know. Unless I’m misunderstanding something
i think so. i'm using cli, it's not working
this is how we configure metro in CLI (credits: Muhammad Awais)
don't forget to run
npx pod-install ios
afterin CLI, it gives this error
`LOG Running "storybook1" with {"rootTag":1,"initialProps":{}}
ERROR Invariant Violation: "storybook1" has not been registered. This can happen if:
AppRegistry.registerComponent
wasn't called., js engine: hermes`