Storybook is an open source tool for developing UI components in isolation. It allows you to visually document components, view different states of each component, and interactively develop and test components. Storybook runs outside of the main app, so you can develop UI components rapidly without worrying about app specific dependencies and requirements.
In this comprehensive guide, I‘ll walk you through getting started with Storybook in a React app. We‘ll cover:
- What is Storybook and why is it useful
- Setting up Storybook in a React app
- An overview of how Storybook works
- Writing stories for components
- Utilizing handy Storybook addons
- Documenting components in Storybook
So let‘s get started!
What is Storybook?
Storybook is essentially a development environment for UI components. It allows you to build components independently and showcase components interactively in an isolated development setup.
With Storybook, you build components as individual entities rather than building them embedded in the main app. This offers several advantages:
- Visual documentation – It‘s a living style guide for your components.
- Develop components faster – No need to spin up the entire app to develop an individual component.
- Test components interactively – Manipulate and test components without any app dependencies.
- Reuse components – promotes reusability by developing components in isolation.
Storybook runs outside of your app in a standalone web server. So you are free to build components without needing to worry about app specific build tooling and requirements.
Storybook supports React, Vue, Angular, HTML and many other frameworks. In this article we‘ll be focusing on React + Storybook.
Setting up Storybook in React
Let‘s set up Storybook in a React project.
Set up the React app
Start off by creating a React project using Create React App:
npx create-react-app storybook-demo
Then cd into the app directory:
cd storybook-demo
Install Storybook
Next, install Storybook with:
npx sb init
This will install Storybook and do some initial setup like creating the config file .storybook/main.js and an example story.
To start up the Storybook development server, run:
npm run storybook
This will launch a development server and open up Storybook in the browser. You‘ll see an intro screen that shows some sample components that come built-in with Storybook.
And that‘s it! Storybook is now integrated into our React app and good to go! Pretty simple setup.
Next let‘s get an understanding of some Storybook basics.
Storybook Basics
Storybook revolves around component stories. Let‘s understand some key concepts:
Stories
A story captures a single visual state of a component. For example, a "Button" component can have stories depicting different button states:
- Default button
- Primary button
- Secondary button
- Disabled button
So stories allow us to showcase components under different configurations independently.
Component Story Format
The stories of a component are defined using Component Story Format (CSF).
// Button.stories.js
import React from ‘react‘;
import { Button } from ‘./Button‘;
export default {
/* 👇 The title prop is optional.
* See https://storybook.js.org/docs/react/configure/overview#configure-story-loading
* to learn how to generate automatic titles
*/
title: ‘Button‘,
component: Button,
};
//👇 We create a “template” of how args map to rendering
const Template = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
primary: true,
label: ‘Button‘,
};
export const Secondary = Template.bind({});
Secondary.args = {
label: ‘Button‘,
};
export const Large = Template.bind({});
Large.args = {
size: ‘large‘,
label: ‘Button‘,
};
The key things to note are:
- Default export is used to set the component title and other metadata
- Each story is an export itself (Primary, Secondary, Large stories in above example)
Templateconstant allows reusing rendering logic between stories- The
.argsproperty sets the arguments that are passed to component to render it in a certain way
So in summary, the default export defines the component itself, and the story exports represent the different component states.
This is the core API to define stories in Storybook!
Addons
Addons are tools that enhance the Storybook experience with extra functionalities like manipulating the component‘s props, handling events, gathering inspection data etc. We‘ll cover useful addons later on.
So in a nutshell:
- 📖 Stories display components under specific configurations
- ⚙️ Addons provide additional dev functionalities to stories
This explains Storybook basics at a high level. Now let‘s start writing some stories!
Writing Component Stories
Let‘s build out some stories for a Button component. This will help solidify our understanding.
Here are the base files for our Button component:
// Button.jsx
import React from ‘react‘;
import ‘./button.css‘;
export const Button = ({ primary, backgroundColor, size, label, ...props }) => {
const mode = primary ? ‘storybook-button--primary‘ : ‘storybook-button--secondary‘;
return (
<button
type="button"
className={[‘storybook-button‘, `storybook-button--${size}`, mode].join(‘ ‘)}
style={backgroundColor && { backgroundColor }}
{...props}
>
{label}
</button>
);
};
/* button.css */
.storybook-button {
font-family: ‘Nunito Sans‘, ‘Helvetica Neue‘, Helvetica, Arial, sans-serif;
font-weight: 700;
border: 0;
border-radius: 3em;
cursor: pointer;
display: inline-block;
line-height: 1;
}
.storybook-button--primary {
color: white;
background-color: #1ea7fd;
}
.storybook-button--secondary {
color: #333;
background-color: transparent;
box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset;
}
.storybook-button--small {
font-size: 12px;
padding: 10px 16px;
}
.storybook-button--medium {
font-size: 14px;
padding: 11px 20px;
}
.storybook-button--large {
font-size: 16px;
padding: 12px 24px;
}
Now let‘s build out some stories for the Button component.
Create a Button.stories.js file:
// Button.stories.js
import React from ‘react‘;
import { Button } from ‘./Button‘;
export default {
title: ‘Example/Button‘,
component: Button,
argTypes: {
backgroundColor: { control: ‘color‘ },
},
};
const Template = (args) => <Button {...args} />;
export const Primary = Template.bind({});
Primary.args = {
primary: true,
label: ‘Button‘,
};
export const Secondary = Template.bind({});
Secondary.args = {
label: ‘Button‘,
};
export const Large = Template.bind({});
Large.args = {
size: ‘large‘,
label: ‘Button‘,
};
Let‘s understand what‘s going on here:
- Default export sets the component
titleand sets metadata likeargTypes Templateconstant allows reuse of rendering logic between stories- Each story export (Primary, Secondary etc.) represents a story
- The
.argsproperty sets the component props to control how it renders
Now run Storybook with:
npm run storybook
You‘ll see the stories rendered for the Button component:

And that‘s it! We created some simple stories showcasing the different visual states of the button component.
You can play around with the component props using the “Controls” addon. This allows you inspect and manipulate props dynamically to further build out more states and edge cases.
Now let’s cover some really useful storybook addons!
Storybook Addons
Addons provide a host of side functionalities to augment story development like manipulating props, handling events, gathering CSS stats etc.
Here are some must-have addons:
Controls
This addon allows you to dynamically modify component prop values within the Storybook UI. Useful for rapidly building and visualizing alternative component states.

Actions
Log UI events like clicks, hovers etc. for debugging and testing:

Viewport
Build responsive components directly within Storybook by manipulating viewport size:

Backgrounds
Visually test components on different backgrounds:

There are many more handy addons available too. Browse the full catalog here.
Next let‘s learn how to leverage Storybook docs to cleanly document components.
Documenting Components
Storybook has awesome documentation abilities through Storybook Docs. It allows documenting components in a visual, interactive format using MDX:

To add component docs, create a .stories.mdx file for that component, for example, button.stories.mdx:
// button.stories.mdx
import { Meta } from ‘@storybook/addon-docs/blocks‘;
import { Button } from ‘./Button‘;
<Meta title=‘Components/Button‘ component={Button} />
# Button
The Button component allows users to trigger actions and events.
<Props of={Button} />
## Variants
Use the `primary` prop to indicate main call-to-action buttons.
<Story name=‘primary‘ args={{ primary: true, label: ‘Button‘ }}>
{props => <Button {...props} />}
</Story>
## Sizes
Use the `size` prop to change button sizes.
<Story name=‘large button‘ args={{ size: ‘large‘, label: ‘Button‘ }}>
{props => <Button {...props} />}
</Story>
Some key things to call out here:
- Use Markdown syntax freely to document components
- Render components via
<Story>tags Propsblock autogenerates props documentationMetacomponent sets the component metadata
For full details see component documentation in the Storybook docs.
And that wraps up our intro to Storybook!
Summary
Here‘s a quick recap of what we covered:
💡 Storybook is a UI component explorer that allows you to develop components in isolation and document them interactively.
📚 Stories capture the different states of a component.
⚙️ Addons augment Storybook with extra functionality to level up component building.
📖 Component documentation helps create a living catalog of components automatically with code samples.
I hope this comprehensive guide helps you get up and running with React Storybook! Let me know if you have any other questions.
Happy Storybooking!