Introduction
Have you ever struggled with maintaining consistency across your UI components or found it challenging to collaborate with designers? I've been there too. After experimenting with several tools, I discovered that Storybook changed my development workflow for the better.
In this post, I'll walk you through setting up Storybook in a React project and show you how to build and document components that you can reuse throughout your applications.
What is Storybook?
It lets you build and test UI components in isolation, away from the complexity of the full app. The interactive documentation makes it easier for team members to understand how components work. Using Storybook, Setting up visual regression tests became surprisingly simple
Getting Started: Project Setup
Let's start by creating our project foundation. Fire up your terminal and run:
npm create vite@latest my-storybook-app -- --template react-ts
cd my-storybook-app
npm install
With our React project ready, let's add Storybook to the mix:
npx storybook@latest init
This command works like magic – it automatically configures Storybook for your Vite setup, creates a .storybook/
folder, and adds some example stories in src/stories/
. Take a moment to explore these files to get familiar with the structure.
Creating Our First Component: The Button
Let's start by building a flexible Button component that we can reuse across our application.
First, create the component file:
// src/components/Button.tsx
import React from 'react';
export interface ButtonProps {
label: string;
onClick?: () => void;
variant?: 'primary' | 'secondary';
}
export const Button: React.FC<ButtonProps> = ({
label,
onClick,
variant = 'primary',
}) => {
const styles = {
primary: 'bg-blue-500 text-white',
secondary: 'bg-gray-200 text-black',
};
return (
<button
className={`px-4 py-2 rounded ${styles[variant]}`}
onClick={onClick}
>
{label}
</button>
);
};
Now for the fun part – creating stories for our Button:
// src/components/Button.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Button } from './Button';
const meta: Meta<typeof Button> = {
title: 'Components/Button',
component: Button,
};
export default meta;
type Story = StoryObj<typeof Button>;
export const Primary: Story = {
args: {
label: 'Click Me',
variant: 'primary',
},
};
export const Secondary: Story = {
args: {
label: 'Cancel',
variant: 'secondary',
},
};
Building a Card Component
Now that we have our Button, let's create a Card component that can even incorporate our Button.
// src/components/Card.tsx
import React from 'react';
export interface CardProps {
title: string;
description: string;
children?: React.ReactNode;
}
export const Card: React.FC<CardProps> = ({ title, description, children }) => {
return (
<div className="border rounded-lg shadow-md p-4 max-w-sm">
<h3 className="text-lg font-bold mb-2">{title}</h3>
<p className="text-gray-700 mb-4">{description}</p>
{children}
</div>
);
};
And here's how we can showcase it in Storybook:
// src/components/Card.stories.tsx
import type { Meta, StoryObj } from '@storybook/react';
import { Card } from './Card';
import { Button } from './Button';
const meta: Meta<typeof Card> = {
title: 'Components/Card',
component: Card,
};
export default meta;
type Story = StoryObj<typeof Card>;
export const Default: Story = {
args: {
title: 'Welcome!',
description: 'This is a sample card component.',
},
};
export const WithButton: Story = {
render: (args) => (
<Card {...args}>
<Button label="Learn More" />
</Card>
),
args: {
title: 'Interactive Card',
description: 'This card includes a button as a child component.',
},
};
I particularly love this example because it shows how components can be nested in Storybook stories, helping you visualize complex component relationships.
Adding Some Style with Tailwind (Optional)
If you're like me and prefer Tailwind for styling, it's super easy to add:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Update your CSS with:
/* in index.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
Don't forget to add your source folder to the content paths in tailwind.config.js
!
Time to See It in Action!
Let's fire up Storybook and see our components:
npm run storybook
When you visit http://localhost:6006/, you'll see your Button and Card components displayed in the Storybook UI. Try clicking around and interacting with different props – it's incredibly satisfying to see your components respond in real-time.
Sharing Your Component Library
Want to share your beautiful components with the team or showcase them in a portfolio? Generate a static build:
npm run build-storybook
This creates a storybook-static/
directory that you can deploy to Netlify, Vercel, GitHub Pages, or any static hosting provider. I've found this especially useful when working with remote teams.
Conclusion
Using Storybook you can develop a consistent design system. Which helps you to onboard new team members more quickly, catch UI bugs before they reach production. Also, you can Communicate more effectively with designers. If you like this blog and want to learn more about Frontend Development and Software Engineering, you can follow me on Dev.to.
Top comments (0)