ScreenshotNeo

BlogGuides

A Practical Storybook Workflow for UI Development

Build and test UI components in isolation with Storybook, from useful stories and accessibility checks to visual review and CI.

By the ScreenshotNeo team4 October 20268 min read

Use Storybook as a workshop alongside your application: render components and pages in isolation, define stories for the states people need to build and review, then add the checks that catch behavior, accessibility, and visual regressions. Keep end-to-end tests for user journeys that depend on the full application and backend.

This workflow gives a team a repeatable catalog of UI states for implementation, review, and CI. The current setup command is npm create storybook@latest; the CLI inspects project dependencies and suggests a configuration. Framework support and runtime requirements change, so check the official installation guide during setup.

1. Install Storybook in the existing project

  1. Open a terminal at the root of the frontend project.
  2. Check the current framework and version requirements. Compatibility thresholds vary, so avoid relying on a copied version list.
  3. Run the current CLI setup command:
npm create storybook@latest

Follow the prompts for the framework and bundler used by the application. Review the generated configuration, package scripts, and sample stories. Confirm the install completed and start the local Storybook using the script the CLI added, commonly:

npm run storybook

Keep the generated configuration aligned with the application’s actual build setup. If the project uses a non-default path, aliases, environment variables, providers, or global styles, configure Storybook to load the pieces components need. Avoid copying secrets into stories or a published Storybook.

2. Model component states as stories

A story is a rendered example of a component in a particular state. Give each important state a stable, understandable example. For a button, that might mean default, disabled, loading, and destructive variants. For a data panel, consider populated, empty, loading, and error states.

// Button.stories.js
import { Button } from './Button';

export default {
  title: 'Controls/Button',
  component: Button,
};

export const Default = {
  args: { children: 'Save changes' },
};

export const Disabled = {
  args: { children: 'Save changes', disabled: true },
};

export const Destructive = {
  args: { children: 'Delete project', variant: 'destructive' },
};

This example uses the current CSF object story style. Adapt the file extension, imports, and component props to the project. Stories should use representative, deterministic data instead of live production services. When a component needs context such as a router, theme, or state provider, supply the same relevant wrapper consistently.

Choose states that earn their place

  • Default: the common state a developer encounters first.
  • Variants: meaningful prop combinations, including sizes, emphasis, and disabled behavior.
  • Lifecycle: loading, empty, success, and error states where applicable.
  • Edge cases: long text, missing optional data, unusual counts, or narrow layouts that could break rendering.
  • Interaction starting points: a stable initial state for actions such as opening a menu or submitting a form.

Do not create a story for every theoretical prop combination. Prioritize states that affect implementation, behavior, or review. A compact catalog is easier to navigate and maintain.

3. Build in isolation and reuse existing patterns

Use the running Storybook to adjust a component without first navigating through the full application. Before introducing a new pattern, browse the catalog: locate a suitable component, inspect its stories for the right variant, and reuse its story definition when wiring it to real application data. Storybook documents this as a way to discover and reuse existing UI patterns.

Keep the boundary clear: stories demonstrate stable UI states; application code supplies production data and full application behavior. If a story depends on time, random values, network access, or mutable shared state, make those inputs deterministic so screenshots and interaction checks are repeatable.

4. Add interaction and accessibility checks

Use interaction checks for important component actions and expected outcomes, such as opening a disclosure, selecting an option, or showing a validation message. Stories can be reused in test tools such as Vitest or Jest. For a Vite project, Storybook’s testing documentation recommends considering its Vitest addon. Choose the integration that fits the project’s existing test setup and consult the testing guide.

Add the accessibility addon to audit rendered DOM against axe-core rules. Findings can include violations, passes, and incomplete checks. An incomplete result needs human review; an automated scan is a useful first QA layer, not proof of accessibility. Configure existing issues as todo when they should be visible as warnings, or use error when violations should fail checks or CI. Follow the accessibility testing guide for current configuration.

  • Use automated checks to surface detectable rule violations in representative stories.
  • Manually review keyboard operation, focus order, labels, reading order, and interaction clarity.
  • Review incomplete findings instead of treating them as passes.

5. Add visual regression checks where they help

Visual testing captures story screenshots and compares them with accepted baselines. Use it for components where accidental appearance changes matter, such as shared controls, complex layouts, and design-system patterns. Review diffs to distinguish intended changes from regressions; a screenshot difference is evidence of a change, not a verdict about whether the change is correct.

Storybook documents Chromatic as a hosted option for cross-browser visual testing and review. See the visual testing guide to compare the current workflow and choose a service that fits the team.

6. Use the right test layer for each failure

Check Question it answers Limit
Interaction/component Does this component respond correctly to an important user action? Does not cover every browser, integration, or complete application path by itself.
Accessibility Does this rendered state have detectable rule violations? Heuristic scans miss issues; incomplete findings need manual review.
Visual regression Did the rendered appearance change from the accepted baseline? A person must review whether a difference is expected.
Unit or snapshot Did logic or rendered markup change from an expected result? Snapshots can require upkeep and do not replace behavior or visual review.
End-to-end Does a real user journey work through the running application stack? Needs the application and its dependencies running; it serves a broader test layer.

Story-level checks are strongest for isolated states. Use Playwright, Cypress, or the project’s end-to-end tool for journeys that depend on routing, backend services, authentication, and application integration. The layers complement one another rather than replace one another.

7. Run repeatable checks in CI and share stories

Choose the checks that provide useful signal for the repository: story tests, accessibility checks, visual comparisons, and end-to-end tests as appropriate. Run them in CI so reviewers can see whether a change passes. Storybook’s testing guide includes a GitHub Actions example with checkout, Node setup, dependency installation, and a Storybook test command. Verify the action, container, and runtime versions against current requirements when implementing it.

Share or publish a Storybook when reviewers need to inspect component behavior and appearance without checking out the branch. Keep the published environment and data appropriate for its audience, and ensure stories do not expose credentials or private data.

8. Capture Storybook states as screenshots

For a one-off screenshot of a local or published Storybook state, use the browser’s developer tools or a browser automation tool such as Playwright. Wait for the story to finish rendering, set the viewport deliberately, and capture the component or full page. For repeatable visual regression, use a story-aware visual testing workflow with baseline comparison.

When capturing manually, account for fonts, animations, asynchronous data, viewport size, and device scale: each can change the resulting image. Prefer stable fixture data, disable or settle animations when appropriate, and wait for the target element before capture. Avoid treating an arbitrary delay as a guarantee that a page is ready.

Or skip the browser setup

ScreenshotNeo is a screenshot API and MCP server for developers. One GET request captures a URL as an image or PDF. See the API documentation for options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://storybook.js.org -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://storybook.js.org"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://storybook.js.org',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
  • Cookie banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
  • Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed. Responses identify the page verdict and billing status in headers.
  • An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
  • The API also supports full-page and element captures, custom CSS and JavaScript, viewport and device options, waits, request blocking, caching, async jobs, and bulk capture.
  • 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000 screenshots. Every feature is on every plan.

Sign up free for 1,000 screenshots a month, with no card required.

Troubleshooting

Symptom Likely cause What to do
CLI does not offer the expected framework Unsupported version, unrecognized dependency, or setup run outside the project root. Run from the repository root and check current framework and runtime support in the install guide.
Story renders without styles or providers Global CSS, theme, router, or context wrapper is not loaded by Storybook. Configure Storybook to include the required stylesheet and decorators/providers.
Story fails while the app works The component expects application state, environment values, or network data that the story does not provide. Supply stable fixtures and the required context; avoid coupling stories to live services.
Interaction test is flaky Unstable data, race conditions, or assertions made before the UI settles. Use deterministic inputs and wait for observable UI state rather than a fixed delay.
Accessibility check reports incomplete The rule needs context or cannot be decided from the DOM alone. Manually inspect the case and record the review outcome; do not treat incomplete as pass.
Visual diff changes on every run Fonts, animation, time, random data, viewport, or asynchronous content varies. Stabilize those inputs and make capture dimensions and readiness conditions consistent.
CI works locally but fails in the pipeline Runtime, browser, package manager, environment, or action/container versions differ. Align CI with current tool requirements and inspect the failing setup step and logs.

Performance, reliability, and cost

Storybook adds a separate development and CI surface, so keep stories focused and avoid unnecessary live integrations. Deterministic fixtures reduce reruns and make review more reliable. Browser-based checks consume time and compute; run high-signal component checks broadly and reserve full-stack flows for the paths that need them. Visual baselines need review and maintenance as designs intentionally change.

Storybook’s core setup is a development workflow; CI and hosted visual testing may have their own infrastructure or service costs. Check current provider terms before adopting a hosted option. For an occasional screenshot outside a visual regression suite, ScreenshotNeo offers a free monthly tier and published paid tiers; consult its site for current details.

FAQ

Can Storybook replace end-to-end tests?

No. It helps exercise isolated UI states. Keep end-to-end tests for journeys requiring the integrated application and backend.

Should every component have a story?

Prioritize reusable or consequential UI and give each story a clear review or testing purpose. Not every internal component needs a large set of examples.

Does an accessibility addon prove a component is accessible?

No. It finds some automated rule violations; manual checks remain necessary, especially for incomplete findings and real keyboard and assistive technology use.

Do visual tests understand whether a change is good?

No. They identify screenshot differences against a baseline. A reviewer decides whether each difference is intentional.