A Guide to Implementing Storybook in Your Enterprise Project (Storybook series part 2)

by Randy — 12 minutes

We know how crucial it is to create high-quality and user-friendly interfaces for enterprise applications. However, managing complex application structures and coordinating multiple teams working on different components can be challenging. That's where Storybook comes in - it's a powerful tool that allows us to develop, test, and showcase UI components in isolation, making it easier to build robust and reusable interfaces. 

You are a medior front-end developer in an enterprise organization. Your job is to create high-quality and intuitive user interfaces. It's a challenging task because you have to manage complicated application structures and maybe coordinate multiple teams working on different parts of an application.

In this article, we'll explore the benefits of using Storybook in enterprise applications and provide a step-by-step guide on installing and using it effectively in your enterprise project. Whether you're a seasoned developer or new to front-end development, this guide will help you streamline your workflow, improve collaboration, and deliver better user experiences for your enterprise application. 

Prerequisites

Before we get started, make sure you have the following installed on your system:

  • Node.js (version 10 or higher)
  • Existing React project

For creating components and stories in this article, we will be using the React library, which offers a robust and intuitive way to build reusable UI components.

You can check out Part 1 of this series, if you're interested in learning more about Storybook. It provides a detailed overview of what Storybook is, how it works, and its benefits for building UI components in isolation. Whether you're new to Storybook or looking to deepen your understanding of the tool, this article is a great place to start.

Step 1: Open your project

First, open your project in your preferred code editor. This tutorial assumes that you have an existing project set up with Vite and React.

Step 2: Install Storybook

Next, open a terminal window and navigate to the root directory of your project. Run the following command to install Storybook:

Using npm.

npx sb init

Or using pnpm.

pnpm dlx storybook@latest init

The script initializes Storybook in your project and creates the necessary files and directories. It automatically detects which framework your project is using and installs the corresponding dependencies and configuration files.

// package.json
 "scripts": {
    "storybook": "storybook dev -p 6006",
    "build-storybook": "storybook build"
  },

In this example, the storybook script launches the Storybook development server by running the storybook dev command with the -p flag set to 6006, which starts the server on port 6006. On the other hand, the build-storybook script generates a static build of your Storybook that can be deployed to a web server by running the storybook build command.

my-project/
├── .storybook/
│   ├── main.js
│   └── preview.js
├── src/
│   ├── stories/

Here's what each folder and file does:

  • .storybook/: This folder contains configuration files for Storybook.
  • main.js: This file specifies the location of your stories and any add-ons you want to use.
  • preview.js: This file allows you to customize the Storybook preview pane.
  • src/: This folder contains the source code for your components and Storybook stories.
  • stories/: This folder contains your Storybook stories.

Step 3: Migrate configuration files to typescript

Your enterprise project is obviously a TypeScript project. Storybook generates JavaScript configuration files so we have to migrate these files to TypeScript.

// .storybook/main.ts

import type { StorybookConfig } from "@storybook/types";

const config: StorybookConfig = {
    staticDirs: ["../public"],
    stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
    addons: [
        "@storybook/addon-links",
        "@storybook/addon-essentials",
        "@storybook/addon-interactions",
    ],
    docs: {
        autodocs: "tag",
    },
    framework: "@storybook/react",
    core: {
        builder: "@storybook/builder-vite",
    },
    features: {
        storyStoreV7: true,
    }
};

export default config;
// .storybook/preview.ts

export const parameters = {
    actions: { argTypesRegex: "^on[A-Z].*" },
    controls: {
        matchers: {
            color: /(background|color)$/i,
            date: /Date$/,
        },
    },
}

Step 4: Import your global styling

Maybe you need global styling because you use a CSS framework or even better, a design system so you have to import the CSS files. The preview config file preview.ts is the configuration file for Storybook that allows you to import global styles.

// .storybook/preview.ts

import '../style/global.css';

Step 5: Create your story structure with atomic design

Your are working on a large application with many components. How do you make sure that your codebase is manageable and easy to update, without sacrificing quality or speed? This is where the atomic design approach comes in.

Atomic design is a methodology that helps you break down your UI into smaller, more manageable parts. By dividing your components into atoms, molecules, and organisms, you can create a shared vocabulary for your team, making it easier to communicate about your UI and reuse components across different parts of your application.

Imagine you're working on a button component. Instead of building the entire button in one go, you can break it down into its atomic parts - the text, the shape, the color, and so on. These atomic parts can then be combined to create molecules - a button with a specific shape, color, and text. Finally, these molecules can be combined to create organisms - a button that's part of a larger UI, like a form or a navigation bar.

By organizing your components into atoms, molecules, and organisms, you make it easier to communicate about your UI and reuse components across different parts of your application. Additionally, by structuring your Storybook stories in the same way, you can easily navigate and explore your UI components, making it easier to develop, test, and document your UI. Overall, using the atomic design approach can help improve your team's productivity, reduce bugs and inconsistencies, and make your UI more flexible and maintainable.

src/  
├── components/  
│   ├── atoms/  
│   │   ├── Button/  
│   │   │   ├── Button.stories.tsx  
│   │   │   └── Button.tsx  
│   │   ├── Input/  
│   │   │   ├── Input.stories.tsx  
│   │   │   └── Input.tsx  
│   │   └── ...  
│   ├── molecules/  
│   │   ├── LoginForm/  
│   │   │   ├── LoginForm.stories.tsx  
│   │   │   └── LoginForm.tsx  
│   │   ├── SearchForm/  
│   │   │   ├── SearchForm.stories.tsx  
│   │   │   └── SearchForm.tsx  
│   │   └── ...  
│   ├── organisms/  
│   │   ├── Header/  
│   │   │   ├── Header.stories.tsx  
│   │   │   └── Header.tsx  
│   │   ├── Sidebar/  
│   │   │   ├── Sidebar.stories.tsx  
│   │   │   └── Sidebar.tsx  
│   │   └── ...  
│   └── ...  
└── ...

In this structure, we have a components directory that contains all of our UI components. The atoms directory contains the most basic building blocks of our UI, such as buttons and inputs. The molecules directory contains slightly more complex components that are composed of multiple atoms, such as login forms and search forms. The organisms directory contains even more complex components that are composed of molecules and/or atoms, such as headers and sidebars.

Each component directory contains a *.stories.tsx file, which is where the component's stories are defined. The *.tsx file contains the component's implementation in TypeScript.

Step 6: Create your stories

A Storybook story represents the rendered state of a UI component and is essentially a function that takes a set of arguments and returns the component with those props. In Storybook, the "args" is used to refer for example to React's props, Vue's props, Angular's @Input, and props & input functionality used in other frameworks. 

By creating variations of stories for your components, you can more easily showcase and document the various states and features of your component in a visual and interactive way.

// uicomponent.stories.ts|tsx

import type { Meta, StoryObj } from '@storybook/react';
import { UIComponent } from './UIComponent';

const meta: Meta<typeof UIComponent> = {
  title: UI Component',
  component: UIComponent,
};

type Story = StoryObj<typeof UIComponent>;
export default meta;

export const VariationA: Story = { args: {} };
export const VariationB: Story = { args: {} };
export const VariationC: Story = { args: {} };
export const VariationD: Story = { args: {} };
  1. Import Statements: At the top of the file, you'll typically see import statements for the component you're creating stories for, as well as any other dependencies you may need.
  2. Title and Component: Next, you'll define a title for your story (which will appear in the Storybook UI) and specify the component you're creating stories for.
  3. Story args: The args are where you define the props for your component.
  4. Variations: Below the Template function, you'll define different variations of your component using Story objects. Each Story object represents a different variation of your component, and you can pass in different props to showcase different features and states of your component.
  5. Export: Finally, you'll export your Meta object and any Story objects you defined so that they can be displayed in the Storybook UI.

Example story

In this example, we have a button component with several features that we want to showcase in our Storybook stories. We define a Meta object that contains metadata about our button component and its stories, such as the title and component name. Then we define a Template function that accepts ButtonProps as arguments and renders a Button component with those props.

After that, we define several Story objects that represent different variations of our button component. For example, the Default story shows the button with no additional props, while the WithIcon story shows the button with an icon prop passed in. We can do the same for stories with different sizes, variants, and states.

// Button.stories.ts

import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';

const meta: Meta<typeof Button> = {
  title: 'Atoms/Button',
  component: Button,
};

export default meta;

type Story = StoryObj<typeof Button>;

export const Default: Story = { args: {} };
export const Small: Story = { args: {} };
export const Large: Story = { args: {} };
export const Primary: Story = { args: {} };
export const Secondary: Story = { args: {} };
export const Disabled: Story = { args: {} };
export const WithIcon: Story = { args: {} };

Using arguments in your story variants can help you more easily test and showcase the various states and features of your components, without having to create separate stories for each variation.

export const Small: Story = { args: {
  size: 'small'
} };
export const Large: Story = { args: {
  size: 'large'
} };
export const Primary: Story = { args: {
  variant: 'primary'
} };
export const Secondary: Story = { args: {
  variant: 'secondary'
} };
export const Disabled: Story = { args: {
  disabled: true
} };
export const WithIcon: Story = { args: {
  icon: <Icon />
} };

Step 7: Deployment

By deploying your Storybook instance, other teams can also easily review and integrate your components into their own projects, saving them time and effort in development. Additionally, Storybook provides a platform for documenting and testing components, which can help ensure consistency and quality across projects. Ultimately, it can facilitate better communication, collaboration, and development practices within your organization.

Deploying Storybook with Github Actions involves creating a workflow file that automates the deployment process. This file includes commands to install dependencies, build your Storybook instance, and deploy it to your desired hosting service. Triggers such as pushing changes to your repository initiate the deployment process.

With Github Actions, you can easily track progress, view logs, and receive notifications. This streamlines development, improves collaboration, and ensures that your components are always up-to-date and available. Here's an example of how you can deploy your Storybook instance using Github Actions

// deploy-storybook.yml

name: Deploy Storybook
on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Install Dependencies
        run: yarn install --frozen-lockfile
      - name: Build Storybook
        run: yarn build-storybook
      - name: Archive Storybook Build
        uses: actions/upload-artifact@v2
        with:
          name: storybook
          path: storybook-static
      - name: Checkout Deploy Branch
        uses: actions/checkout@v2
        with:
          ref: gh-pages
          fetch-depth: 0
      - name: Copy Storybook Build
        run: cp -R ${{ github.workspace }}/storybook-static/* .
      - name: Commit and Push Changes
        uses: EndBug/add-and-commit@v7
        with:
          message: 'Deploy Storybook'
          add: '.'
          branch: gh-pages
          author_name: ${{ github.actor }}
          author_email: ${{ github.actor }}@users.noreply.github.com
      - name: Clean up Deploy Branch
        run: git branch -D gh-pages

Conclusion

To summarize, using Storybook in an enterprise project can significantly enhance the front-end development process, leading to the creation of high-quality and reusable interfaces. By enabling developers to develop, test, and demonstrate UI components in isolation, Storybook helps streamline workflows, boost collaboration, and deliver improved user experiences. 

This article provided a detailed guide on effectively installing and utilizing Storybook in an enterprise project, emphasizing the use of atomic design approach for creating components and stories. By following these guidelines and harnessing the potential of Storybook, front-end developers can improve their efficiency and build superior UIs for enterprise applications.

meerdivotion

Cases

Blogs

Event