Skip to main content
/tayyab/portfolio — zsh
tayyab
TA
// dispatch.read --classified=false --access-level: public

Playwright Component Testing in 2026: Still Experimental — Should You Use It?

April 15, 2026 EST. READ: 11 MIN #Quality Assurance

Every few weeks someone on a team I'm working with asks the same question: "Should we switch our component tests from Vitest/Jest to Playwright Component Testing?" The answer is more nuanced than the docs admit. Playwright CT has been marked experimental since its initial release, and as of 1.59 it's still experimental. The team isn't moving fast on it because their resources are going into the agentic primitives (see my 1.59 agents post).

I've shipped Playwright CT on one production project and avoided it on three others. Here's the honest take on when it's the right tool, when it isn't, and what the decision actually looks like.

Table of Contents

What Playwright Component Testing Actually Is

Playwright CT mounts your component in a real browser (Chromium, Firefox, WebKit) and lets you interact with it using the same APIs as full E2E tests. Compare that to Vitest which mounts the component in JSDOM (a fake browser environment) or Jest with React Testing Library (also JSDOM, with helper utilities).

// playwright/tests/Button.spec.tsx
import { test, expect } from '@playwright/experimental-ct-react';
import { Button } from '../src/Button';

test('button click fires onClick', async ({ mount }) => {
  let clicked = false;
  const component = await mount(
    <Button onClick={() => clicked = true}>Click me</Button>
  );
  await component.click();
  expect(clicked).toBe(true);
});

That's the API. Looks like normal Playwright, but the test runs in isolation against a single component instead of a full app.

Where the Experimental Status Really Matters

The package name itself tells you the score: @playwright/experimental-ct-react. Three things make this matter in production:

  1. Breaking changes between minor versions. The mount API has changed twice since 1.40. Each change required updating every test file. If you have 200 component tests, that's a half-day of mechanical work each time.
  2. Limited framework support. Stable for React. Functional for Vue and Svelte. Removed for Svelte in 1.59 (the experimental-ct-svelte package was deprecated). Solid is unsupported. Lit is unsupported.
  3. No agent integration in 1.59. The new planner/generator/healer agents don't generate component tests. They're trained on full-app E2E patterns.

The Playwright maintainers have signaled, on multiple GitHub threads, that component testing is a side project for them — useful for testing Playwright itself, not a focus area for the framework's external users.

When It's the Right Tool

Three scenarios where I'd reach for Playwright CT:

1. Components that depend on real browser APIs

JSDOM doesn't implement: layout, scrolling behavior, focus management edge cases, IntersectionObserver in detail, ResizeObserver, drag-and-drop, file drop, clipboard. If your component logic depends on these, JSDOM tests give you false confidence. Playwright CT runs in real Chromium and tests them properly.

Example: a virtualized list that uses IntersectionObserver to load more items. JSDOM stubs IntersectionObserver and your test never exercises the real lazy-load. In Playwright CT, scrolling actually triggers the observer.

2. Visual regression on individual components

Playwright CT pairs naturally with toHaveScreenshot() for component-level visual diffs. Storybook + Chromatic does this too, but more expensively. If you're already in the Playwright ecosystem and need basic visual regression, CT plus screenshots is a clean fit.

3. Testing components in isolation that have many user interactions

A custom date picker with keyboard navigation, mouse interactions, and edge cases around focus traps benefits from real-browser testing. JSDOM gets focus management subtly wrong in ways that don't matter for most components but break for complex ones.

When to Use Vitest or Jest Instead

Most projects, most of the time. Specifically:

1. Pure logic components

A component that takes props, renders some text, and fires a callback. JSDOM is fine. Vitest runs your test in 50ms; Playwright CT takes 1.5 seconds because it has to spin up a browser context. Multiplied across 500 component tests, the difference is a 12-minute test suite versus a 25-second test suite.

2. Heavy mocking required

Vitest's vi.mock and Jest's jest.mock are mature. Playwright CT's mocking story is less developed — you can intercept network requests, but mocking ES modules requires more setup. If your component depends on five injected services, the mocking overhead in Playwright CT will outweigh the real-browser benefits.

3. Snapshot testing as your primary strategy

Vitest snapshots are first-class. Playwright CT can do screenshots but doesn't have a great equivalent for serialized component output. If you're snapshot-heavy, stay with Vitest.

4. Frameworks Playwright CT doesn't fully support

Solid, Lit, Qwik, Astro components — none have first-class Playwright CT support in 1.59. Use Vitest with the appropriate plugin.

My One Production Project (and What I'd Do Differently)

I shipped Playwright CT on a healthcare client. The decision: yes, because the design system had a complex dialog component with focus-trap, escape-key handling, and outside-click detection — all things JSDOM gets weird about. The team had ~40 component tests for this dialog alone, and we wanted real browser confidence.

What worked:

  • Real focus management testing caught two bugs Vitest had been masking.
  • Visual regression on the design system caught a Tailwind purge issue that broke spacing.
  • Keyboard navigation tests felt rock-solid versus the previous JSDOM approximations.

What I'd do differently:

  • I'd keep the rest of the design system (~200 simpler components) on Vitest. We migrated everything for consistency, and it cost us 8 minutes per test run for components that didn't need real browser semantics.
  • I'd version-pin Playwright CT and not auto-update. Every minor version brought subtle API changes; the maintenance overhead was real.

Hindsight: a hybrid approach (Playwright CT for the 30 components that need it, Vitest for the 200 that don't) would have given the same coverage at half the CI cost.

The Decision Tree

For each component or component family, ask:

  1. Does the component logic depend on real browser APIs (IntersectionObserver, focus management edge cases, drag-drop)? If yes → Playwright CT.
  2. Do you need visual regression and don't already have Chromatic/Storybook? If yes → Playwright CT with toHaveScreenshot.
  3. Are you testing pure rendering/logic with mocked dependencies? Vitest or Jest.
  4. Is your framework Solid/Lit/Qwik/Astro? Vitest with plugin.
  5. Default if unsure? Vitest. The bar to switch should be a specific need that JSDOM can't meet.

Where This Is Heading

Two indicators about the trajectory:

  • The Svelte CT removal in 1.59 suggests the team is consolidating, not expanding, framework support.
  • The agent primitives in 1.59 don't extend to component testing. The roadmap energy is on E2E + AI, not CT.

My read: Playwright CT will remain experimental, get incremental improvements, and stay viable for the React/Vue use cases it currently supports. Don't expect it to expand. If you need component testing at scale across multiple frameworks, the safer bet is staying with the framework-native option (Vitest, Jest) and using Playwright for E2E.

FAQs

Will Playwright CT exit experimental?

The maintainers have not committed to a timeline. Issue #26778 has been the canonical thread for two years and the answer remains "no near-term plans." Plan around the experimental status, not against it.

What replaced experimental-ct-svelte after the 1.59 removal?

Vitest with the Svelte testing library is the official recommendation. Migration is mechanical for most tests.

Is component testing in Cypress better?

Cypress Component Testing is more mature and out of experimental. If your team is already on Cypress, their CT is a reasonable choice. If you're starting fresh, the speed cost of any browser-based component testing is the same; pick based on your team's existing tooling.

Can I run Playwright CT and full E2E in the same project?

Yes. You'd set up two separate Playwright projects — one for CT (uses @playwright/experimental-ct-react), one for E2E (uses @playwright/test). Different runners, different configs.

How does Playwright CT compare to Storybook interactions?

Storybook's interaction tests run in JSDOM by default. @storybook/test-runner can run them in real browsers (it uses Playwright under the hood). Storybook's stronger differentiator is the visual catalog and component documentation; if you only need testing, Playwright CT is more direct.

Does Playwright CT support hot module reload during development?

Yes — npx playwright test --ui watches your component files and reruns affected tests. Decent dev experience.

What about server components (Next.js App Router, RSC)?

Out of scope for component testing entirely. Server components don't render in the browser; they render on the server and stream HTML. Test them via integration tests (full Next.js app + Playwright E2E) or unit-test the data fetching logic separately.

Can I use the Playwright agents (planner/generator/healer) with CT?

Not in 1.59. The agents are trained on full-app E2E patterns. Component-level test generation isn't supported. If this matters to you, file a feature request — though the maintainers' focus is elsewhere right now.

Does Playwright CT integrate with React Server Components?

It can mount client components but not server components. If your client component depends on a server component for data, you'll need to mock that data at the prop level.

Is the migration from Vitest to Playwright CT painful?

Moderate. The mounting API differs, mocking is different, and you'll spend time on per-test setup. Expect 30–60 minutes per test file for the conversion. Don't migrate unless the real-browser benefit is worth it for those specific components.

Wrap-Up

Playwright Component Testing is a useful tool for a narrow band of components — those whose behavior genuinely depends on real browser APIs. It is not a Vitest replacement, and treating it as one results in slower CI, breaking changes between releases, and a dependency on an experimental package the maintainers are not heavily investing in.

If you're evaluating component testing strategy for a design system or a complex frontend codebase, that's a question I scope under framework engagements. Or book a free call and we'll talk through the decision tree for your specific stack.

Related reading:

Tayyab Akmal
// author

Tayyab Akmal

AI & QA Automation Engineer

6 years of catching critical bugs in fintech, e-commerce, and SaaS — then building the Playwright and Selenium automation that prevents them from shipping again.

// feedback_channel

FOUND THIS USEFUL?

Share your thoughts or let's discuss automation testing strategies.

→ Start Conversation
Available for hire