Getting Started with Storybook: React Component Library Example

Sofa

In a hurry? Skip to the tutorial! You can see the live example here and the GitHub repo here.

Designing, building, and organizing user interface (UI) components can require a lot of collaboration between designers and developers. And even though modern JavaScript frameworks have made it easier to create modular systems, it still can be a pain to organize and have a broader point of view.

Organizing UI components pain without storybook

Luckily for us, new tools are beginning to pop up, improving the collaboration process of designing and implementing UI components. These tools, like Storybook with React, decouple your business logic from individual pieces of the UI, making implementing and integrating a component library conforming to your design system more straightforward for app developers and system design engineers.

But how can you start using these kinds of tools, you might be wondering?

Well, that’s what we’ll explore with this Storybook & React tutorial.

Here’s what I’ll cover:

  • What Storybook is?
  • How can it save you valuable time when working with components?
  • How to set up a Storybook instance that is co-located with a React application?
  • How to create the first instance of a component along with its story?
  • How do various prop values affect the component’s appearance and functionality?

So with no further ado, let’s jump in it.

What is Storybook?

Storybook

Storybook is a JavaScript open-source tool to improve the developer’s engineering experience while creating reusable UI components. It’s designed to work with various front-end frameworks, like React, Vue, and Angular.

You can think of Storybook as a catalog or guidebook of the UI’s building blocks, including visual and written documentation for their various states and intended usage.

Developing components with Storybook is a lot faster since they can be produced in isolation (without complete business logic integration). Edge cases can also be quickly documented both with visual and code examples. Another nice aspect of most Storybook instances is functionality that allows effortlessly manipulating values and seeing the impact on how a component renders in the browser.

In addition to the core Storybook software, various add-ons can be configured to customize a particular Storybook instance and add more advanced functionality. Storybook also maintains a catalog of the multiple add-ons available.

Storybook addons

What are the advantages of using Storybook IRL?

Well, Storybook is a very powerful way to document design systems.

Its visual aspects allow it to be relevant for other stakeholders of the design system beyond engineers. Storybook is also perfect for presenting robust technical documentation and quickly demoing technical implementation details and how specific configurations will impact the functionality and appearance of component rendering in browsers. Some of this documentation can be autogenerated by Storybook based on the types associated with a particular component.

Developing components outside of Storybook can make the full breadth of their functionality (in terms of visuals, accessibility, and behavior) less visible. Since the component documentation within Storybook is very closely tied to its implementation and usage, it’s easier to ensure that Storybook documentation is kept up to date. It also means that the documentation can be viewed as a source of truth which may not always be the case when referencing a design file that may or may not be the latest version in the official repository where the UI blocks are hosted.

Tutorial: Using Storybook with Next.js (or a React project)

React (Next.js) & Storybook

In this tutorial, I’ll focus on walking through integrating Storybook into a Next.js/React project.

Note that Storybook v6.3 is designed to work with React but also Vue, Angular, Web Components, Ember, HTML, Mithril, Marko, Svelte, Riot, Preact, and Rax.

Pre-requisites

  • Node
  • NPM (Node Package Manager)
  • Yarn (package manager)
  • Basic knowledge of React

Step 0: Creating a new React app with Next.js

Before we start our adventure with Storybook, we’ll first need to create an up and running Next.js app so that we can install Storybook in it.

For those of you who aren’t already familiar with Next.js, it’s a popular React framework that supports both static and server-side rendered pages out of the box.

If you don’t already have a React application to which you would like to add Storybook, you can first create one by initializing a Next.js application. In your terminal, run the following:

npx create-next-app

or

yarn create next-app

The command above will generate a new Next.js application in the directory in which it was run and will have the same name you provided when running the prompts.

For example, if you named it nextjs-storybook-example, you should run the following in your terminal to navigate to it:

cd nextjs-storybook-example

Step 1: Initialize Storybook in your React app

Now that we have our React application up and running, we’ll need to install and set up our local instance of Storybook.

The following command should be run within the directory of the application in which we want to install Storybook:

npx sb init

The command above will quickly set up the boilerplate needed for a working Storybook instance. npx is the npm package runner installed alongside npm since [email protected] If you’re curious to learn more about npx, this Node.js guide has more information.

Next, we need to ensure that all the required dependencies are installed at the root of the project by running:

yarn` or `npm install

Step 2: Run Storybook locally

Now let’s look at our instance of Storybook by running:

Yarn storybook

Once the command has successfully run, a working version of Storybook should start running at http://localhost:6006/ with some example stories and links to helpful documentation.

Storybook React example welcome page

Step 3: Create First Component for Storybook

Inside our project folder, we can see a Storybook directory with a stories folder inside, which was autogenerated when we ran sb init.

In it, we’ll be adding the UI blocks we would like to add to Storybook. I’ve decided to add this functional Banner.jsx component within the stories folder with the following code:

/** @jsxImportSource @emotion/react */
import React from "react";
export default function Banner({ variant = "info", children }) {
  return (
   <aside
   >
     {children}
   </aside>
 );
}
 
Banner.propTypes = {
 variant: "info" | "congrats" | "documentation" | "danger",
};

The PropTypes or TypeScript types are used by Storybook to autogenerate some of the documentation in stories.

A CSS object can be used to apply different styles on different variants dynamically. Emotion is a library that enables writing CSS objects with JavaScript. You can install Emotion with:

npm install @emotion/react` or `yarn add @emotion/react

In order for Emotion to process the CSS in JS properly, we should add the following line to the top of the Banner.jsx file:

/** @jsxImportSource @emotion/react */

Below is an example of how different styles can be applied to a react component based on the value of a prop. However for the complete Banner styles reference the Banner.jsx file in the GitHub example associated with this tutorial:

/** @jsxImportSource @emotion/react */import React from "react";export default function Banner({ variant = "info", children }) { const variantStyles = {   info: {     borderLeft: "4px solid #b4aaff",     backgroundColor: "rgba(224, 226, 255, 0.5)",     color: "#2a2135",     "&:before": {       content: '"🔑"',       backgroundColor: "#b4aaff",     },   },   danger: {     borderLeft: "4px solid #ff7828",     backgroundColor: "rgb(253, 236, 234)",     "&:before": {       content: '"⚠️"',       backgroundColor: "#ff7828",     },   },   congrats: {     borderLeft: "4px solid #72bc23",     backgroundColor: "rgb(249, 253, 234)",     "&:before": {       content: '"🎉"',       backgroundColor: "#72bc23",     },   },   documentation: {     borderLeft: "4px solid #44a9ba",     backgroundColor: "rgb(234, 248, 253);",     "&:before": {       content: '"📚"',       backgroundColor: "#44a9ba",     },   }, }; return (   <aside     css={{       ...variantStyles[variant],     }}   >     {children}   </aside> );}

The variantStyles object has keys with specific styles for each of the variants the Banner supports. I.e., If the value of the variant prop is “documentation”, then we’ll apply the styles contained in variantStyles[documentation] aside.

Here’s an example:

{     borderLeft: "4px solid #44a9ba",     backgroundColor: "rgb(234, 248, 253);",     "&:before": {       content: '"📚"',       backgroundColor: "#44a9ba",     },   },

Step 4: Create First Story

After adding a file to the stories folder, we need to add an associated story file to view the component in Storybook. This new file should be added to the stories folder with the name [Component].stories.jsx to be adequately detected by the default Storybook configuration.

In this example, I created Banner.stories.jsx and imported the Banner component created in the previous step. I also added metadata to the default export as Storybook uses this information to list stories and provide additional details about particular parts.

Within this same file, I also defined named constants that render the Banner with different props. Storybook will automatically convert into stories with the same name as the constant.

    import React from "react";    import Banner from "./Banner";    export default {     title: "Example/Banner",     component: Banner,    };    export const Info = () => (     <Banner variant="info">       <p>         This is an example of an info banner to display important information.       </p>     </Banner>    );    export const Danger = () => (     <Banner variant="danger">       <p>This is an example of a danger banner to display warnings.</p>     </Banner>    );    export const Congrats = () => (     <Banner variant="congrats">       <p>This is an example a congrats banner to celebrate a win!</p>     </Banner>    );    export const Documentation = () => (     <Banner variant="documentation">       <p>         This is an example a documentation banner to highlight relevant reading         materials and documentation.       </p>     </Banner>    );

Step 5: View Story in Storybook

Let’s revisit the Storybook instance and navigate to the component we just created.

In my instance, I selected Banner from the side navigation and clicked on docs, which directed me to http://localhost:6006/?path=/docs/example-banner--info.

This particular documentation view contains a summary of all of the various Banner stories that we defined in the previous steps and highlights their visual differences. It also includes a button “Show code” that can be toggled to view the JSX and generate that particular element.

Storybook React Banner

Step 6: Use a Story in our React app

To use the stories in our React application, we can import the created Banner.jsx file into a Next.js file like index.js.

import Banner from "../stories/Banner.jsx";

Then we can use the component the same way we would normally do by writing an instance of it with the appropriate props and children HTML/text like below:

 <Banner variant="info">         <p>           This is an example of how we can use our components from Storybook           in a NextJS application. JSX components that are defined in           Storybook can be imported/exported like regular JSX components. If           you need to import components from Storybook in external applications           then you should explore publishing a NPM package that contains the           relevant components.         </p>       </Banner

Adding Banner.jsx above the header of our Next.js index.js renders a page that looks something like this:

Next.js Storybook banner page example

The example above shows how to import components from Storybook when the stories are co-located within the same project. However, if you would need to import them from Storybook in an external application, you should try publishing an NPM package that contains exports of the Storybook components. This will enable you to import them across projects.

You can see the live example here and GitHub repo here.

Closing thought

Overall, I found that Storybook’s capability of allowing components to be viewed and manipulated in isolation can be helpful for quickly understanding the nuisances between various UI components and how various props impact how they render.

Instead of going through the process of manually manipulating props and refreshing to see what they look like, Storybook enables me to gather the same information more quickly without having to write additional code or having the application run locally. Stakeholders across the project can reference Storybook early on and throughout the production process to determine if a particular design is already implemented in code, should be added, or a pre-existing one should be expanded. Faster discovery to go from a design prototype to a working implementation significantly reduces the time it takes to build a new user experience (UX) within a design system.

With its core features and robust plugin library, Storybook is a solid choice for creating both visual and technical documentation of design systems that encourage collaboration and decrease the amount of time it takes to go from design to implementation.

Have you tried Storybook? Let me know what your thoughts are in the comments below.

Suggested posts: