Cypress vs. Storybook: A Test Runner and a Workshop, Not Rivals
They overlap on one thing and solve different problems. What each catches, what browser binaries cost every CI install, and four defects here that neither would have found.
Cypress and Storybook are not alternatives to each other. Cypress is a test runner that drives a real browser and asserts behaviour; Storybook is a component workshop that renders components in isolation so you can build, document and review them. They overlap on exactly one capability — rendering a single component in a browser — and teams that run both use Cypress to verify and Storybook to build.
So "Cypress vs Storybook" is usually the wrong question. The useful one is: which class of defect am I buying coverage for, and what does that coverage cost to install and keep? This post answers that, and then gives the honest third data point — this storefront runs neither, and the defects it actually shipped say something about why.
The short answer
| Cypress | Storybook | |
|---|---|---|
| Primary job | Run tests against a browser | Build and document components in isolation |
| Catches | Broken user flows, wrong behaviour, regressions | Visual and API drift, unclear component contracts |
| Scope | Whole app (E2E) or one component | One component, one state at a time |
| Assertions | Core feature | Via addons (interaction, visual regression) |
| Produces docs | No | Yes — a browsable component catalogue |
| Runs in CI | Yes, headless | Yes, via its test runner or a visual-diff service |
| Needs the app to boot | Yes for E2E, no for component tests | No |
| Dev dependency weight | Heavy (browser binaries) | Heavy (its own build pipeline) |
| Best fit | Apps with flows worth regression-testing | Design systems and shared component libraries |
Pick Cypress if your risk is "the checkout broke and nobody noticed." Pick Storybook if your risk is "nobody knows this component has eleven props and three of them conflict." Pick both if you maintain a component library that an app depends on — that is the case where their jobs genuinely stack, and Cypress's Storybook integration lets you reuse stories as test fixtures.
Where the overlap actually is
Cypress component testing was the feature that made this comparison a real question. It renders a single component in a real browser, without routing or booting the rest of the app, which is substantially what Storybook does — and it is faster and less flaky than an E2E test of the same component, because there is no page load or navigation in the way.
What it does not give you is the artefact. Cypress component tests leave behind a pass/fail result; Storybook leaves behind a browsable catalogue that a designer, a PM, or a new engineer can open. If the reason you were considering Storybook is "our components are undocumented," Cypress does not solve it, and the reverse is also true: Storybook's interaction testing addon writes assertions, but you would not build an E2E suite in it.
Running them together is supported and costs setup. Reusing stories as Cypress fixtures means the test runner, the story and the component all participate in the render, and some Storybook features (controls, knobs) have historically not carried over. It is worth it when the stories already exist; it is not a reason to create them.
The third option, with numbers
This storefront is a Next.js 16 marketplace: 772 prerendered pages, 92 component files, 111 products. It runs no Cypress, no Storybook, and no component tests of any kind. That is not a recommendation — it is a data point about what kind of codebase can skip both, and what it needs instead.
What it does run, measured on the current tree:
npm test
# Test Files 31 passed (31)
# Tests 391 passed (391)
# Duration 7.44s (transform 4.50s, tests 2.85s)
391 assertions in 2.85 seconds of actual test time, with one dev dependency (vitest) and no browser. The suite grew from 273 tests at an earlier quality gate to 391, and it has not needed a browser yet, because of what it asserts: data and logic invariants, not rendered output. src/data/__tests__/blog.test.ts is representative — 18 assertions covering whether slugs are unique and URL-safe, whether every post has a registered loader and every loader a post, whether dates are real calendar dates, whether internal link targets resolve to products and pages that exist.
The reason that is enough here is the shape of the codebase: 92 components, of which 68 are Server Components with no interactivity at all, rendering content that comes from typed arrays. The defect that actually hurts is not "the button does not open" — it is "the button links to a product that was retired," and no component test finds that.
The defects it did ship, and what caught them
Four real ones, each caught by something that is neither Cypress nor Storybook:
/bloghad no<h1>at all. Caught by a Lighthouse accessibility audit, after the page had been live./docsskipped fromh1toh3. Same audit.BlogTagmissed AA contrast by a hundredth —text-primary(#465fff) onbg-primary-25(#f2f7ff) at 12px measures 4.49:1 against a 4.5:1 requirement.- The "Keep reading" rail concentrated every internal link on 12 posts out of 178 — three of them collecting 111 inbound links each — leaving 166 posts with none. Caught by writing a data invariant, after Search Console reported 35 uncrawled posts.
That list is the argument of this whole post. Numbers 1–3 are rendering defects, exactly the category Storybook is for — and a story would have rendered all three without complaint, because a story shows you a component, and all three are properties of the page the component lands on, or of a contrast ratio no human eye catches at 0.01. What found them was an automated audit against real built pages. Number 4 is a property of a data structure across 178 items, which no browser-based tool of either kind would surface; what found it was 20 lines of arithmetic over an array, and it is now a permanent assertion:
✓ spreads inbound rail links evenly instead of concentrating them
npm test now fails if any post drops to zero inbound rail links or one collects more than six. That assertion is cheap, instant, and guards a defect that cost real indexing.
The install cost nobody budgets for
The axis most comparisons skip, and the one that decided it here. Playwright is used in this repo — for screenshot capture, not testing — and it is deliberately not a dependency:
// scripts/release/capture-gallery.mjs
//
// playwright is NOT a dependency of the storefront (it would cost every CI
// install for a script that runs a few times a year) -- install it ad hoc:
// npm install --no-save playwright
import { chromium } from "playwright";
A browser-driving tool means browser binaries in every CI install, on every pull request, forever. For a script that runs a few times a year, --no-save is the right trade. For a test suite that must run on every push, you cannot dodge it that way — the cost is permanent, and it is the real price of both Cypress and Storybook. Worth pricing explicitly before adopting either, because it is paid by every contributor and every CI minute, not just by the person who set it up.
Which to choose, by what you are building
| Your situation | Reach for | Why |
|---|---|---|
| Shared component library, several consumers | Storybook | The catalogue is the deliverable, not a side effect |
| App with a checkout, auth, or multi-step flow | Cypress | Those flows break silently and cost money |
| Design system plus the app that consumes it | Both | Stories as fixtures; Cypress asserts the behaviour |
| Content/data-driven site, mostly Server Components | Neither yet | Your defects are in the data — assert the invariants first |
| Deciding between component tests and E2E | Cypress component tests first | Faster, less flaky, no routing or app boot |
The row to argue with is the fourth, so here is the condition on it: it holds while your interactive surface is small and your content surface is large. The moment this storefront gained a checkout, a download authorisation path and an account dashboard, it gained flows worth E2E coverage — and that is the point at which Cypress starts earning its install cost here. The logic underneath those flows is currently covered by unit tests instead (entitlements, download authorisation, webhook signature verification, refund eligibility), which is cheaper and catches a different, narrower set of bugs. That is a deliberate position with a known gap, not a claim that browser tests are unnecessary.
Mistakes and troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| Storybook adopted, bugs still ship | Stories render components; they do not assert behaviour | Add the interaction/visual-diff addons, or a test runner |
| Cypress suite is slow and flaky | E2E-testing things that are component-level | Move those to Cypress component tests — no routing, no app boot |
| Stories drift from the real app | Story props are maintained separately from the call sites | Import the real data/types into the story instead of inlining props |
| CI install time doubled after adopting either | Browser binaries now download on every install | Cache the browser path in CI; audit whether the tool must run on every push |
| Reused stories fail inside Cypress | Controls/knobs and decorators do not all carry over | Keep fixture stories plain, without addon-dependent features |
| Both tools green, accessibility still broken | Neither audits a real built page by default | Add an automated a11y audit against built routes |
| Both tools green, links point nowhere | Rendered output is correct; the data is wrong | Assert data invariants in a plain unit test |
Frequently asked questions
Is Storybook a testing tool? Not by itself. It renders components in isolation and documents them; assertions come from addons (interaction testing, visual regression) or from an external runner. If you need pass/fail in CI, that is a decision on top of Storybook, not something it gives you.
Can Cypress replace Storybook? For verifying a component's behaviour, largely yes — its component tests render in a real browser without booting the app. For documenting a component so other people can discover it, no. Cypress produces results; Storybook produces a catalogue.
Do I need either for a static marketing site? Usually not. On a content-driven site most defects are in the data and the markup semantics, which plain unit tests and an automated accessibility audit catch faster and for a fraction of the install cost.
What about Playwright instead of Cypress? Playwright covers the same E2E ground with multi-browser support and a different API, and it carries the same browser-binary install cost. This repo uses it, but for screenshot automation rather than testing — see Playwright automated screenshots, and Playwright vs Vitest for the testing comparison.
Templates in this post
ASoc Amplify is a social-media-management SaaS marketing site with services, results stats and a journal. ASoc Atelier is a designer's portfolio and studio site with selected work, services and a booking funnel. ASoc Axiom is a neural-networks AI-consultancy landing page with four services, an FAQ and project-based pricing.
Browse the full sets: Next.js landing page templates, Tailwind landing page templates.
