DEV Community

Cover image for How to Easily Set Up a React Storybook App
Kyle McKell
Kyle McKell

Posted on • Updated on

How to Easily Set Up a React Storybook App

One of the greatest parts about React is the giant ecosystem of components created by thousands of devs all over the world.

I'm sure you've wondered at some point, how can I contribute something of my own to this? Is it simple? How can I share only my components without just pasting raw code? I suppose I could just have a project with no UI, but then how would I test my components? ๐Ÿ˜•

I'm going to go over how to create and test your UI library. Here we go! ๐Ÿš€

Enter Storybook ๐Ÿ“•

Storybook is an open source tool that makes creating UI libraries extremely easy. Let's get your Storybook project up and running! ๐Ÿƒโ€โ™€๏ธ

๐ŸงถNote: I am going to be using yarn throughout this tutorial, however, any package manager works

Let's head over to our terminal and set up a new yarn project

# Creating a new directory to put our project into
mkdir storybook-demo

# Changing our current directory to our project directory
cd storybook-demo

# Setting up a yarn project (feel free to use the -y flag)
yarn init

# Opening our directory in our text editor (I use VSCode)
code .
Enter fullscreen mode Exit fullscreen mode

Now let's open up our package.json that was created in our directory, if you're using yarn it'll look like this:

{
  "name": "storybook-demo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT"
}
Enter fullscreen mode Exit fullscreen mode

Let's head back to our terminal and add React to our project

# Add react and react-dom to devDependencies
yarn add react react-dom -D
Enter fullscreen mode Exit fullscreen mode

Now your package.json should look something like this:

{
  "name": "storybook-demo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "react": "^17.0.1",
    "react-dom": "^17.0.1"
  }
}
Enter fullscreen mode Exit fullscreen mode

Sweet! Now let's create an src folder.

# create an src folder
mkdir src
Enter fullscreen mode Exit fullscreen mode

Cool, we'll mess with the folder structure a little more, but this is sufficient to reliably set up Storybook in our project.

Go ahead and run this in your terminal:

npx sb init
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“Note: Make sure you have react in your project before running this command, storybook uses information provided in your package.json to initialize itself

As you wait for this to work its โœจmagicโœจ, you can take a trip over to the Storybook docs to read a little more about it.

One that finishes, you'll notice some differences to your project, let's start by going into our package.json

{
  "name": "storybook-demo",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "@babel/core": "^7.13.10",
    "@storybook/addon-actions": "^6.1.21",
    "@storybook/addon-essentials": "^6.1.21",
    "@storybook/addon-links": "^6.1.21",
    "@storybook/react": "^6.1.21",
    "babel-loader": "^8.2.2",
    "react": "^17.0.1",
    "react-dom": "^17.0.1"
  },
  "dependencies": {},
  "scripts": {
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"
  }
}
Enter fullscreen mode Exit fullscreen mode

Great! Storybook has recognized that we have react in our project (as seen with the @storybook/react dependency). Also take note of the two new scripts that have been added to our project, we'll look more at the first one later.

If you've never used storybook before, feel free to run this command and explore!

# for yarn
yarn storybook

# for npm
npm run storybook
Enter fullscreen mode Exit fullscreen mode

If you look at your file structure, you'll also notice two new folders have been introduced: .storybook and src/stories

For the means of this tutorial, we are going to leave .storybook alone, as all of the default configurations suit our needs. Refer to the docs if you find the need to change things up.

But let's take a look into the src/stories folder

You'll see something looking like this:

src/stories
| /assets
| button.css
| Button.js
| Button.stories.js
| header.css
| Header.js
| Header.stories.js
| Introduction.stories.mdx
| page.css
| Page.js
| Page.stories.js
Enter fullscreen mode Exit fullscreen mode

Take note of how this is structured, as this is entirely viable Storybook code! However, I think we can make something more robust and more easily scalable by bettering the file structure of our project

So let's delete the contents!

# change to stories directory
cd src/stories

# remove the contents
rm -rf *
Enter fullscreen mode Exit fullscreen mode

We'll come back to that later... let's set up a UI component! We'll be making a simple button, but feel free to make whatever you would like

# change to our src directory (assuming you're in src/stories)
cd ..

# create a components directory
mkdir components

# change to our components directory
cd components

# create a Button.js file in our components directory
touch Button.js

# open Button.js in our editor
code Button.js
Enter fullscreen mode Exit fullscreen mode

For the sake of simplicity, we're going to keep this component pretty barebones, we can iterate more on this later.

// src/components/Button.js
export const Button = () => {
    return <button>I am a Button!</button>;
};
Enter fullscreen mode Exit fullscreen mode

Now we need to set up a story for our Button. Let's create a file:

# Go to stories dir (if you're still in src/components)
cd ../stories

# Create a Button.stories.js in our stories directory
touch Button.stories.js

# Open it in our editor
code Button.stories.js
Enter fullscreen mode Exit fullscreen mode

Still with me? Now let's put in some code to test out Storybook

We can think of our story as a mini React project. We'll walk through the basics of making a story, but you can check out the docs on a more in depth explanation of what a story is here

Go ahead and put this into your Button.stories.js file:

// Button.stories.js

// import React and stories from storybook
import React from "react";
import { storiesOf } from "@storybook/react";

// import our Button component
import { Button } from "../components/Button";

// create our stories
const stories = storiesOf("Button Test", module);

// add to our stories
stories.add("Button", () => {
    return <Button />;
});
Enter fullscreen mode Exit fullscreen mode

This simple story is going to just display our Button component that we created earlier, as to maintain simplicity

Also! Since our story behaves like a React app, we need to import React. This also applies if we choose to use hooks.

Now let's see if our story works!

# for yarn
yarn storybook

# for npm
npm run storybook
Enter fullscreen mode Exit fullscreen mode

You should see something like this pop up in your browser:

Storybook localhost UI

Great! Now everything is up and running. We can do just about anything we want with our storybook, from creating an entire UI library, to testing out how our different UI components work together.

I'll give a quick (albeit very very simple) example with the Button component that we made. After that I'll send you off on your own! โœˆ

// src/components/Button.js
export const Button = ({
    bgColor = "lightblue",
    children = "Button",
    ...props
}) => {
    return (
        <button style={{ backgroundColor: bgColor }} {...props}>
            {children}
        </button>
    );
};
Enter fullscreen mode Exit fullscreen mode

This simple Button component takes in a bgColor prop, it's children, and then also passes it's rest of its props (for instance 'onClick')

Now let's make this do something within our story!

// src/stories/Button.stories.js

import React from "react";
import { storiesOf } from "@storybook/react";

import { Button } from "../components/Button";

const stories = storiesOf("Button Test", module);

stories.add("Button", () => {
    const handleClick = () => {
        alert("You clicked the button!");
    };

    return (
        <Button bgColor="white" onClick={handleClick}>
            This is the Button's children
        </Button>
    );
});
Enter fullscreen mode Exit fullscreen mode

I added in an onClick handler, a prop for our bgColor, and filled in the Button's children with some generic text.

And with our Storybook magic, we've created this! ๐ŸŽ‰

Storybook app UI with new Button code

I hope this tutorial was helpful to you! I personally plan on using Storybook for creating any UI based libraries I make, what about yourself?

Until then, code on! ๐Ÿ‘ฉโ€๐Ÿ’ป

PS: Here's the source code

Top comments (1)

Collapse
 
100000multiplier profile image
multiply.today

very nice tutorial, thank you!