Storybook to App Workflow
Overview
Storybook is for developing components in isolation. The actual components live in your codebase and are imported by both Storybook stories AND your app.
┌─────────────────────┐
│ Component File │ ← The real component
│ Button.jsx │
└─────────────────────┘
↓ imported by both
┌────┴────┐
↓ ↓
┌────────┐ ┌──────────┐
│ Story │ │ App │
│ .jsx │ │ .jsx │
└────────┘ └──────────┘The Complete Workflow
1. Create a Component
File: src/components/Button.jsx
jsx
import React from 'react'
export default function Button({
variant = 'primary',
children,
...props
}) {
return (
<button className={`btn btn-${variant}`} {...props}>
{children}
</button>
)
}2. Create a Storybook Story
File: src/components/Button.stories.jsx
jsx
import React from 'react'
import '../tailwind.css'
import '../styles.css'
import Button from './Button' // ← Import the real component
export default {
title: 'Components/Button',
component: Button,
tags: ['autodocs'],
argTypes: {
variant: {
control: 'select',
options: ['primary', 'ghost']
},
children: {
control: 'text'
}
}
}
export const Primary = {
args: {
variant: 'primary',
children: 'Click me'
}
}Purpose: Develop, test, and document the component in isolation.
3. Use Component in Your App
File: src/App.jsx (or any other app file)
jsx
import React from 'react'
import Button from './components/Button' // ← Same import!
export default function App() {
return (
<div>
<Button variant="primary" onClick={() => alert('Clicked!')}>
My Button
</Button>
</div>
)
}Real Example from This Project
Icon Component
Component: src/components/Icon.jsx
jsx
export default function Icon({name, size = 16, ...props}) {
// ... implementation
}Story: src/components/Icon.stories.jsx
jsx
import Icon from './Icon'
export const Logo = {
args: { name: 'logo', size: 28 }
}Used in App: src/App.jsx
jsx
import Icon from './components/Icon'
// In render:
<Icon name="logo" size={36} />Key Points
✅ DO:
- Create component once in
src/components/ComponentName.jsx - Import it in the story:
import ComponentName from './ComponentName' - Import it in your app:
import ComponentName from './components/ComponentName' - Develop and iterate in Storybook
- Use the same component in your app
❌ DON'T:
- Define components inline in story files (unless it's just for the story)
- Copy/paste between Storybook and app
- Maintain separate versions
Workflow Best Practices
Development Flow:
Build in Storybook - Develop component with all variants
bashnpm run storybookTest interactively - Use Controls panel to test different props
Import to app - Use the component where needed
jsximport Button from './components/Button'Iterate - Make changes to the component file, see updates in both Storybook AND app
File Organization:
src/
├── components/
│ ├── Button.jsx ← Real component
│ ├── Button.stories.jsx ← Storybook story
│ ├── Button.test.jsx ← Tests (optional)
│ ├── Icon.jsx
│ └── Icon.stories.jsx
├── App.jsx ← Uses Button and Icon
└── merchant/
├── Dashboard.jsx ← Can also use Button/Icon
└── OfferForm.jsxCommon Patterns
Pattern 1: Simple Import
jsx
// Component: src/components/Alert.jsx
export default function Alert({ type, message }) {
return <div className={`alert-${type}`}>{message}</div>
}
// Story: src/components/Alert.stories.jsx
import Alert from './Alert'
export const Error = {
args: { type: 'error', message: 'Something went wrong' }
}
// App: src/App.jsx
import Alert from './components/Alert'
<Alert type="error" message="Login failed" />Pattern 2: With Multiple Exports
jsx
// Component: src/components/Card.jsx
export function Card({ children }) { /* ... */ }
export function CardHeader({ children }) { /* ... */ }
export function CardBody({ children }) { /* ... */ }
// Story: src/components/Card.stories.jsx
import { Card, CardHeader, CardBody } from './Card'
// App: src/App.jsx
import { Card, CardHeader, CardBody } from './components/Card'Why This Workflow?
- Single Source of Truth - Component exists in one place
- Live Documentation - Storybook shows how to use each component
- Isolated Development - Build without worrying about app context
- Reusability - Same component works everywhere
- Team Collaboration - Designers/developers can review in Storybook
Next Steps
- Check the updated App.jsx to see Button and Icon in action
- Open Storybook at http://localhost:6007 to see the stories
- Try changing
Button.jsx- changes appear in both Storybook and the app!
See Also
- ADDING_STORIES.md - How to write stories
- Storybook CSF Documentation