Getting Started with Storybook: How to Develop React Components Without an App
Tags: beginners, react, javascript
Published: 2020-10-21 14:37:33

---
title: Getting Started with Storybook: How to Develop React Components Without an App
published: true
tags: beginners, react, javascript
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/rzec6nzr8h7f2gle5mk5.jpg
canonical_url: https://welearncode.com/storybook/
---

I wanted to write up some thoughts and a quick tutorial on one of my favorite development tools, Storybook. You can use Storybook which allows you to develop user interface components in isolation. It can also aid in development and documentation of design systems -- which are sets of components and design standards that companies develop to be used across their apps.

## What is a Design System

Large companies normally have multiple applications -- external facing, internal facing, and cross-platform. It can be difficult to unify the design across these platforms. So, many companies are implementing design systems to help create unified design across all of their products and platforms. [Here](https://airbnb.design/building-a-visual-language/) is a great example of how Airbnb implements their design system.

You may have heard of a component library before -- these are collections of components that you can import and use in your projects. A design system extends this to also include style and content guidelines and other rules for future design work. [This](https://uxdesign.cc/do-you-think-your-component-library-is-your-design-system-think-again-7e2c902b5275) is a great post about how design systems go beyond component libraries.

## How does Storybook help?

Storybook really helps with the development process of design systems and component libraries. [Here](https://storybook.grommet.io/?path=/story/all--all) is an example of Grommet, an accessible React component library's, full Storybook. Normally, you'd have to build out a whole app in order to see your components as you create them. Storybook allows you to develop components independently so you can focus on styling and interaction. You can use it with many different frontend libraries such as React, Angular, Vue, or even just with HTML.

## Tutorial

In this tutorial, we'll use React to build out a mini-component library that has a few different types of buttons to see how Storybook works! If you're new to React, check out [this](https://welearncode.com/complete-beginners-guide-react-2020/) post to get up to speed before continuing on with this tutorial.

First, create a React app: `npx create-react-app storybook-tutorial`. Then, change into its directory: `cd storybook-tutorial`.

Now, install storybook and initialize it: `npx -p @storybook/cli sb init`.

This command adds a `.storybook` folder with configuration information about your project. It also adds a `/stories` folder inside your `/src` directory that shows a demo Storybook project. We'll go ahead and **delete that folder** , but you can take a peek at the code if you want!

Run: `npm run storybook` to get Storybook up and running -- it should pop up in your browser and give you a message about no stories being found.

Now, we'll go ahead and create a `Button` directory: `mkdir Button` and add three files inside of it, one for the component, one for the CSS, and one for the stories: `touch Button.{js,css,stories.js}`.

Here's a recap of all the steps from above:

```sh
$ npx create-react-app storybook-tutorial
$ cd storybook-tutorial
$ npx -p @storybook/cli sb init
$ rm -rf /src/stories
$ npm run storybook
$ mkdir /src/Button
$ touch /src/Button/Button.{js,css,stories.js,test.js}
```

Now, we'll make a React component in the `Button.js` file -- it will just render a button and use the `children` prop for text. This allows us to instantiate our button component like `<Button>my text</Button>` and then our component would render a `button` element with `my text` on it!

```jsx
// Button.js
import React from 'react'
import './Button.css'

export default function Button({ children }) {
  return (
    <button>{children}</button>
  )
}
```

Now we'll go ahead and create a couple stories. A story is a display of a state of a component. We'll have collections of stories for different types of elements. For example, we can have a collection of different versions of our Button component.

We'll go ahead and add our Button stories to `Button.stories.js`. First, we need to import React so we can use JSX in the file. Then we'll import our Button component.

Next, we'll add a default export from this file which will have metadata about our collection. In this case, I'm titling the collection `Button`. This will render on our Storybook UI as almost a directory name.

We'll also export two functions that instantiate our `Button` component with different text on it.

All together, our code will look like this!

```jsx
// Button.stories.js

import React from 'react'
import Button from './Button'

export default {
  title: 'Button'
}

export const DefaultButton = () => <Button>hi!</Button>
export const SecondButton = () => <Button>hello!</Button>
```

If you check back on your Storybook window, it should look like this:

![two buttons showing up on the UI](https://welearncode.com/storybook/storybook-two-components.png)

There's a Button collection label with two different buttons: Default and Second. You can click between the buttons and see each one's different text. If we were just using React, we would need to build an app to view the component -- here we can develop them independently just by creating stories.

Let's think of the different types of buttons we may have in our design system. Maybe a default outlined one, a disabled one, a primary button and then maybe different states -- hover and click for example. We may also have different sizes of buttons. What we can do is add props that differentiate these different factors and then based on those props add CSS classes to our buttons.

We'll first make it so that we have an outline button and a default button.

First, add the following CSS:

```css
/* Button.css */
button {
  background-color: #FF389C;
  color: white;
  font-size: 20px;
  padding: 10px;
  border: none;
  border-radius: 4px;
}

button:focus {
  outline: 2px solid pink;
}

.outline {
  background-color: white;
  color: #FF389C;
  border: 2px solid #FF389C;
}
```

Then, we'll tweak our storybook file to export a default button and an outline button instead of the default and second button that we have now:

```jsx
export const DefaultButton = () => <Button>click me!</Button>
export const OutlineButton = () => <Button outline>click me!</Button>
```

Then, we need to conditionally add the outline class to our button if it has the `outline` prop:

```jsx
import React from 'react'
import './Button.css'

export default function Button ({ children, outline }) {
  let classes = ''
  if (outline) classes += 'outline '
  return (
    <button className={classes}>{children}</button>
  )
}
```

![storybook interface with outline button](https://welearncode.com/storybook/outline-default-button.png)

Now, if you look at Storybook the two buttons reflect our two different types of buttons!

Let's also make it so that we can have small and large buttons.

```css
/* Button.css */
.small {
  font-size: 10px;
  padding: 6px;
}

.large {
  font-size: 20px;
  padding: 10px;
}
```

We'll add two more button stories:

```jsx
export const SmallButton = () => <Button size='small'>click me!</Button>
export const LargeButton = () => <Button size='large'>click me!</Button>
```

If you wanted, you could add small and large outline buttons too!

We'll also add the size to the `classes`:

```diff
import React from 'react'
import './Button.css'

+ export default function Button ({ children, outline, size }) {
  let classes = ''
  if (outline) classes += 'outline '
+ classes += size
  return (
    <button className={classes}>{children}</button>
  )
}
```

Now you should have four stories!

![](https://welearncode.com/storybook/four-components.png)

There are a couple things you could do now: you could use [actions](https://storybook.js.org/docs/react/essentials/actions) to test out event handling. You could use your `Button` in an app by importing it into a page of a React app -- you could also deploy it to `npm` so that you could use it in projects more easily in the future. You can also deploy your storybook so that other people can visit it by running `npm run build-storybook` and then using static site hosting for the folder that is produced from that command.

Storybook is such a great development tool, especially if you're a design-focused frontend developer. I hope that this was a helpful tutorial, feel free to [tweet at me](https://twitter.com/ASpittel) with what you'd like to see a tutorial on next!