📚 Storybook
Develop and test React components in isolation with interactive controls and documentation.
The astro-basics project uses Storybook for interactive component development and Chromatic for automated visual regression testing. Together, they provide a complete solution for testing and documenting React components.
📚 Storybook
Develop and test React components in isolation with interactive controls and documentation.
🎨 Chromatic
Automated visual regression testing that catches unintended UI changes before they ship.
♿ Accessibility
Built-in a11y addon for WCAG compliance checking on every component.
🔄 CI Integration
Seamless GitHub Actions integration for automated testing on every PR.
# Start Storybook development servernpm run storybook
# Opens at http://localhost:6006# Build for deploymentnpm run build-storybook
# Run visual regression tests (loads .env automatically)npm run chromatic
# Override token for one-off runsCHROMATIC_PROJECT_TOKEN=<your-token> npm run chromaticStories are co-located with their components:
src/components/react/├── Alert.tsx├── Alert.stories.tsx # Story file├── RoleBadge.tsx└── RoleBadge.stories.tsx # Story fileStorybook is configured to support the project’s # path aliases:
viteFinal: async (config) => { config.resolve.alias = { '#components': new URL('../src/components', import.meta.url).pathname, '#utils': new URL('../src/utils', import.meta.url).pathname, '#libs': new URL('../src/libs', import.meta.url).pathname, '#types': new URL('../src/types', import.meta.url).pathname, '#constants': new URL('../src/constants', import.meta.url).pathname, } return config}| Addon | Purpose |
|---|---|
@storybook/addon-essentials | Docs, controls, actions, viewport, backgrounds |
@storybook/addon-interactions | Testing component interactions |
@storybook/addon-a11y | Accessibility testing |
import type { Meta, StoryObj } from '@storybook/react'import Alert from './Alert'
const meta = { title: 'Components/Alert', component: Alert, parameters: { layout: 'centered', }, tags: ['autodocs'], argTypes: { type: { control: { type: 'select' }, options: ['error', 'success', 'info'], description: 'The visual style of the alert', }, },} satisfies Meta<typeof Alert>
export default metatype Story = StoryObj<typeof meta>
export const Error: Story = { args: { type: 'error', children: 'This is an error message.', },}export const Success: Story = { args: { type: 'success', children: 'Operation completed successfully!', },}
export const Info: Story = { args: { type: 'info', children: 'Here is some helpful information.', },}
export const LongContent: Story = { args: { type: 'info', children: 'This is a longer message that demonstrates how the component handles more content.', },}export const AllVariants: Story = { render: () => ( <div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}> <Alert type="error">Error alert</Alert> <Alert type="success">Success alert</Alert> <Alert type="info">Info alert</Alert> </div> ),}Essential patterns:
satisfies Meta<typeof Component> for type safetytags: ['autodocs'] for automatic documentationargTypes for interactive controlslayout: 'centered' for most componentsThe project includes stories for these components:
| Component | File | Stories |
|---|---|---|
| Alert | Alert.stories.tsx | Error, Success, Info, LongContent |
| RoleBadge | RoleBadge.stories.tsx | Member, Volunteer, TeamManager, TeamAdmin, Admin, SuperAdmin, AllRoles |
Create a Chromatic account at chromatic.com
Link your repository and create a new project
Copy your project token from the Chromatic dashboard
Add the token to .env (loaded automatically):
CHROMATIC_PROJECT_TOKEN=<your-token>Run Chromatic (extra flags forwarded):
npm run chromatic1. Build
Chromatic builds your Storybook and captures screenshots of every story.
2. Compare
Screenshots are compared against baselines to detect visual changes.
3. Review
Changes are flagged for review in the Chromatic dashboard.
4. Approve
Accept intentional changes or flag regressions for fixing.
Add Chromatic to your GitHub Actions workflow:
name: Chromatic
on: push: branches: [primary] pull_request: branches: [primary]
jobs: chromatic: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'npm'
- name: Install dependencies run: npm ci
- name: Run Chromatic uses: chromaui/action@latest with: projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }} exitZeroOnChanges: trueThe @storybook/addon-a11y addon provides automated accessibility checks:
npm run storybook)| Issue | Solution |
|---|---|
| Missing alt text | Add alt attribute to images |
| Low contrast | Adjust color combinations for 4.5:1 ratio |
| Missing labels | Add aria-label or visible labels |
| Focus indicators | Ensure visible :focus styles |
| Heading hierarchy | Use sequential heading levels (h1 → h2 → h3) |
| Script | Description |
|---|---|
npm run storybook | Start dev server on port 6006 |
npm run build-storybook | Build static Storybook |
npm run chromatic | Run visual regression tests (loads .env, forwards extra flags) |
If you see errors like Cannot find module '#utils/...':
.storybook/main.ts has correct alias configurationtsconfig.json settingsCHROMATIC_PROJECT_TOKEN is setnpm run build-storybookEnsure your story files:
*.stories.tsx or *.stories.tssrc/components/react/// ✅ Good - focused, typed, documentedconst meta = { title: 'Components/Button', component: Button, tags: ['autodocs'], argTypes: { variant: { control: 'select', options: ['primary', 'secondary'], }, },} satisfies Meta<typeof Button>E2E Testing
Project Documentation
Storybook Docs
Chromatic Docs
The Storybook and Chromatic setup provides:
Key Takeaway: Write stories for all component variants, review Chromatic changes before merging, and fix accessibility violations early!