EmpireUI
Get Pro
← Blog7 min read#playwright#cypress#testing

Playwright vs Cypress in 2026: Testing Real Next.js Applications

Playwright vs Cypress in 2026 — which E2E framework actually holds up when testing Next.js App Router apps? A developer's honest breakdown with real config and code.

Developer writing automated tests on a dark-themed code editor with terminal output visible

Honestly, Playwright Has Already Won — But Cypress Isn't Dead

Honestly, if you're starting a new project in 2026 and you haven't already picked a framework, Playwright is the default choice for most Next.js teams. That's not a hot take anymore. It's just where the ecosystem landed.

But Cypress 13 is still very much alive. It ships with component testing that feels more integrated than Playwright's equivalent, and if your team already has thousands of Cypress tests, migrating isn't something you do on a Tuesday afternoon. Real codebases have inertia.

This article isn't here to tell you which one is objectively better. It's here to walk through the actual trade-offs — version numbers, config quirks, Next.js App Router gotchas — so you can make a call that fits your situation. No hand-waving.

Setup and Installation: What Actually Takes Time

With Playwright 1.48.2, setup is one command: npm init playwright@latest. It scaffolds a playwright.config.ts, creates example tests, and offers to install browser binaries — Chromium, Firefox, WebKit — all in one go. The whole thing takes maybe three minutes if your network is decent.

Cypress 13.17.0 has improved its setup story considerably. npm install cypress --save-dev then npx cypress open drops you into a guided UI that walks through folder structure and config. It's genuinely nice for teams new to E2E testing. The catch is that Cypress still installs a full Electron shell, which adds around 400MB to your node_modules. On CI this matters more than you'd think.

For a Next.js 15 project using the App Router, you'll also want to configure base URLs and dev server startup in both tools. Playwright handles this natively in playwright.config.ts with a webServer block. Cypress needs a separate plugin like start-server-and-test or a custom script. Small friction, but it adds up.

Writing Tests: Syntax, Locators, and the Day-to-Day Experience

Playwright's locator API is where it really shines. page.getByRole('button', { name: 'Submit' }) reads like a sentence. It's close to how Testing Library works, which means your team's mental model transfers. Auto-waiting is baked in — no cy.wait(1000) hacks.

Cypress has cy.findByRole() via the Testing Library plugin, but it's an add-on. Out of the box you're writing cy.get('[data-testid="submit"]') a lot, which leaks implementation details into your tests. Cypress 13 added cy.intercept() improvements and better retry logic, but the selector ergonomics still lag behind Playwright's built-ins.

Here's a real example. Testing a form submission in a Next.js Server Action flow looks like this with Playwright:

import { test, expect } from '@playwright/test';

test('contact form submits and shows confirmation', async ({ page }) => {
  await page.goto('/contact');

  await page.getByLabel('Your email').fill('test@example.com');
  await page.getByLabel('Message').fill('Hello from Playwright 1.48');
  await page.getByRole('button', { name: 'Send message' }).click();

  // Wait for Server Action to resolve and UI to update
  await expect(
    page.getByText('Thanks! We\'ll be in touch.')
  ).toBeVisible({ timeout: 8000 });
});

The equivalent Cypress test isn't dramatically harder, but you'll likely need cy.intercept() to mock or observe the Server Action POST, because Cypress can't natively await network-coupled UI updates as cleanly. With Next.js App Router and Server Actions firing at /, that interception gets tricky.

Next.js App Router Compatibility: Where Things Get Complicated

The App Router changed a lot of testing assumptions. Route handlers, Server Components, Server Actions, streaming responses — none of these exist in the browser in the traditional sense. Both tools test through the browser, so they see the rendered output. But the path to that output matters.

Playwright handles streaming SSR cleanly. If your page uses Suspense boundaries and streams content in chunks, Playwright's waitForLoadState('networkidle') or locator-based waiting deals with it correctly. We've tested this against Next.js 15.2 with fetch cache revalidation — it works without special config.

Cypress has more friction here. Streaming responses can confuse Cypress's network layer. There are community workarounds, but you'll hit them. If your app leans hard on React Server Components with progressive hydration — and many 2026 apps do — this is a real operational cost, not a hypothetical edge case. It's also worth considering how your choice of framework affects your overall Next.js vs Remix architectural decisions, since testing complexity differs across those stacks too.

CI Performance: Pipeline Minutes Cost Money

Playwright's parallel execution is built-in and excellent. You specify workers: 4 in config, and tests shard across processes with zero extra setup. On GitHub Actions with an ubuntu-latest runner, a 200-test Playwright suite consistently finishes in under 3 minutes with 4 workers.

Cypress parallelization requires Cypress Cloud — which is a paid service. The free tier gives you 500 test results per month, then you're paying. For small teams that's fine. For a startup running CI on every PR and every push, it adds up fast. Self-hosted parallelization is possible but requires significantly more orchestration work.

Docker image sizes tell the same story. The official mcr.microsoft.com/playwright:v1.48.2-noble image is around 1.8GB but includes all three browsers and Node 22. Cypress's official Docker images are similar in size but require more configuration to run headlessly in non-Electron mode. If you're optimizing your pipeline and watching build costs, this feeds directly into the pnpm vs npm vs yarn conversation — every MB and every second matters in monorepo CI.

Component Testing: Where Cypress Fights Back

Cypress Component Testing is genuinely good. If you want to test a React component in isolation — rendered in a real browser, not jsdom — Cypress handles this with less friction than Playwright's experimental component testing. The DX is closer to Storybook interaction testing than to a traditional E2E suite.

You mount a component, interact with it, assert on its output. For a UI library like Empire UI versus Tailwind UI, component-level browser tests are actually quite valuable — you can verify that glassmorphism styles render correctly, that dark mode toggling works at the CSS variable level, that animations don't break layout.

Playwright's component testing (@playwright/experimental-ct-react, as of 1.48.2 still experimental) works but requires more boilerplate. It's getting better every release cycle, but right now if component testing is your primary use case, Cypress wins the experience comparison. That gap might close in 2027.

Debugging Failures: Traces, Screenshots, and Time-Travel

Playwright Trace Viewer is one of its strongest selling points. When a test fails in CI, you get a .zip artifact that you open in npx playwright show-trace. You see every DOM snapshot, every network request, every console log, timeline-scrubbing included. Debugging a flaky test that only fails on CI goes from a half-day nightmare to a 20-minute investigation.

Cypress Dashboard (now Cypress Cloud) offers video recordings and screenshot diffs. It's polished and works well. But it's behind the paid tier for teams above the free limit, and the self-hosted alternative doesn't have trace-level granularity. The free open-source debugging story is just worse.

Is there a scenario where Cypress's debugging tools are good enough? Absolutely. For smaller teams, the Cypress test runner UI with hot-reload during local development is excellent. Seeing the test execute step-by-step in a real browser, clicking back through command history — that flow is genuinely fast for writing new tests. It's not the same as Trace Viewer, but it's not nothing either.

Which One Should You Actually Pick in 2026

New project, App Router, no existing test suite: use Playwright. Install it in 3 minutes, write tests that read like real user interactions, parallelize for free on CI. That's the path with the least long-term friction.

Existing Cypress suite with solid coverage: don't migrate unless you're hitting real pain points. Cypress 13 is maintained, the component testing is legitimately good, and migration costs are rarely worth it just for principle. Fix the flaky tests first.

Mixed architecture — some component tests, some E2E flows, maybe some visual regression: consider running both. It sounds expensive but Playwright for E2E and Cypress for component tests is a real pattern in large codebases. The test runner binaries are the only duplicate cost, and on CI you're already paying per-minute anyway. Pair this with solid tooling choices — like the ones outlined in Vite vs Next.js — and your dev experience stays coherent end to end.

For Empire UI itself, we run Playwright for integration tests across the 40 visual styles, checking that theme toggles apply correctly, that style buttons don't cause layout jumps, and that glassmorphism effects render consistently across Chromium and Firefox. Component-level visual tests run in Storybook. That split has worked well since Next.js 14.

FAQ

Can Playwright test Next.js Server Actions directly?

Not at the network layer — Server Actions are just POST requests to the page's route. Playwright tests through the browser UI, so you interact with the form, trigger the action, and assert on the resulting UI change. You can also use page.route() to intercept and mock those POST requests if you need to test error states without a real backend.

Does Cypress support Next.js 15 App Router without extra plugins?

Basic navigation and form interactions work fine. The friction comes with streaming SSR responses, Server Components, and React 19 concurrent features. Some patterns require cy.intercept() workarounds or waiting strategies that Playwright handles automatically. Check the Cypress Next.js compatibility docs for your specific version before committing.

Is Playwright's component testing production-ready in 2026?

It's still marked experimental in the @playwright/experimental-ct-react package as of 1.48.2. Many teams use it successfully, but the API can change between minor versions. For production component testing in a browser environment, Cypress Component Testing is currently more stable and better documented.

How do I run Playwright tests in parallel on GitHub Actions for free?

Use the shards strategy in your workflow matrix combined with --shard=N/M in the Playwright CLI. For example, splitting into 4 shards across 4 parallel jobs cuts your CI time by roughly 75%. Playwright merges shard results with npx playwright merge-reports — no paid service required.

What's the real cost difference between Playwright and Cypress on CI at scale?

Playwright parallelization is fully free and built-in. Cypress parallelization via Cypress Cloud costs $67/month for the Starter plan (as of late 2026) and covers 50,000 test results. If you're running 500+ tests per PR across dozens of PRs per week, that ceiling hits fast. Factor this in before choosing.

Can I use both Playwright and Cypress in the same project?

Yes, and it's more common than you'd think. A typical split is Playwright for full E2E flows (authentication, checkout, form submission) and Cypress for component-level browser tests. The test commands live separately in package.json and CI can run them independently. The main cost is maintaining two config files and two sets of type definitions.

Free components in 40 styles
React & Tailwind, copy-paste ready.
Browse →

Read next

Cypress vs Playwright in 2026: E2E Testing ShowdownBun vs Node.js for Next.js: Real Benchmark ResultsPlaywright E2E Tests for React Apps: Setup, Fixtures, CIPlaywright Component Tests: Browser-Real Testing for React