# How to Test React Components with Cypress: The Complete Guide

> Learn how to test React components directly with Cypress using the @cypress/react adapter. Mount and interact with your components in a real browser for robust testing.

- Repository: [Cypress.io/cypress](https://github.com/cypress-io/cypress)
- Tags: how-to-guide
- Published: 2026-06-18

---

**Cypress can test React components directly using the `@cypress/react` adapter, which mounts components in a real browser via React 18's `createRoot` API and exposes them to standard Cypress commands like `cy.get()` and `cy.click()`.**

The cypress-io/cypress repository provides first-class support for React component testing through its dedicated Component Testing feature. By leveraging the `@cypress/react` package bundled with the main Cypress CLI, you can import the `mount` function to render individual React components in isolation and interact with them using Cypress's full browser automation capabilities.

## How Cypress Mounts React Components

Cypress tests React components by creating a specialized test harness that bridges React's rendering layer with the Cypress command chain. This architecture is implemented in the `npm/react` package and follows a precise lifecycle:

1. **Provides a DOM container** – The `@cypress/mount-utils` utility supplies a hidden `<div>` element in the Cypress test runner page via `getContainerEl`.

2. **Creates a React root** – Using **React 18's** `ReactDOM.createRoot` (as seen in [`npm/react/src/mount.ts`](https://github.com/cypress-io/cypress/blob/main/npm/react/src/mount.ts) lines 13‑18), Cypress maintains a single `root` instance for the component lifecycle.

3. **Renders the JSX** – The supplied JSX is passed to `ReactDOM.Root.render` (see [`mount.ts`](https://github.com/cypress-io/cypress/blob/main/mount.ts) lines 55‑60).

4. **Exposes Cypress commands** – The `mount` call returns a `Cypress.Chainable`, allowing you to chain standard commands against the mounted component.

5. **Handles cleanup** – A `cleanup` helper unmounts the previous component before each new `mount` call (see [`mount.ts`](https://github.com/cypress-io/cypress/blob/main/mount.ts) lines 15‑25), ensuring isolated test state between assertions.

## The Mount API Implementation

The core implementation lives in [`npm/react/src/mount.ts`](https://github.com/cypress-io/cypress/blob/main/npm/react/src/mount.ts). This file exports the `mount` function that integrates React 18's concurrent rendering features with Cypress's testing infrastructure.

When you call `mount()`, the adapter checks for existing React roots and creates a new one if necessary:

```typescript
// From npm/react/src/mount.ts (lines 13-18)
import { getContainerEl } from '@cypress/mount-utils'

const container = getContainerEl()
const root = ReactDOM.createRoot(container)

```

The rendering process then delegates to the React root:

```typescript
// From npm/react/src/mount.ts (lines 55-60)
root.render(
  <StrictMode>
    {component}
  </StrictMode>
)

```

Between test runs, the cleanup mechanism ensures no state leaks:

```typescript
// From npm/react/src/mount.ts (lines 15-25)
const cleanup = () => {
  if (root) {
    root.unmount()
  }
}

```

## Setting Up Component Testing

According to [`npm/react/package.json`](https://github.com/cypress-io/cypress/blob/main/npm/react/package.json), Cypress component testing requires no separate installation of the React adapter for typical use cases. The package declares React as a peer dependency and provides convenience scripts in your [`package.json`](https://github.com/cypress-io/cypress/blob/main/package.json):

```json
{
  "scripts": {
    "cy:open": "cypress open --component",
    "cy:run": "cypress run --component"
  }
}

```

These scripts launch Cypress in component-testing mode, which configures the test runner to use the `@cypress/react` adapter automatically.

## Writing Your First React Component Test

Create a test file with the [`.cy.jsx`](https://github.com/cypress-io/cypress/blob/main/.cy.jsx) or [`.cy.tsx`](https://github.com/cypress-io/cypress/blob/main/.cy.tsx) extension and import the `mount` function from `@cypress/react`:

```tsx
// Counter.cy.jsx
import { mount } from '@cypress/react'
import { Counter } from './Counter'

it('increments the counter when clicked', () => {
  mount(<Counter />)
  
  cy.get('[data-cy=increment]').click()
  cy.get('[data-cy=counter]').should('have.text', '1')
})

```

This test mounts the `Counter` component in a real browser, then uses standard Cypress commands to interact with it and assert on the rendered output.

## Advanced Mount Options

### Custom Wrapper Components

You can wrap your component with providers or context using the `wrapper` option:

```tsx
import { mount } from '@cypress/react'
import { ThemeProvider } from './ThemeProvider'

it('renders with theme context', () => {
  const wrapper = ({ children }) => (
    <ThemeProvider>{children}</ThemeProvider>
  )

  mount(<MyComponent />, { wrapper })
  cy.get('[data-theme]').should('exist')
})

```

### Forcing Rerenders

To test component updates with new props, use a unique key for each `mount` call:

```tsx
import { mount } from '@cypress/react'

it('updates when props change', () => {
  const Comp = ({ text }) => <span>{text}</span>

  mount(<Comp text="first" />, {}, 'key-1')
  cy.contains('first')

  mount(<Comp text="second" />, {}, 'key-2')
  cy.contains('second')
})

```

The third argument (`key`) forces React to unmount the previous instance and mount a new one with the updated props.

## Summary

- **Cypress tests React components** through the `@cypress/react` adapter, which is bundled with the main Cypress CLI.
- **The `mount` function** creates a React 18 root via `ReactDOM.createRoot` and renders your JSX into a hidden container provided by `@cypress/mount-utils`.
- **Automatic cleanup** occurs between tests via the `cleanup` helper in [`mount.ts`](https://github.com/cypress-io/cypress/blob/main/mount.ts), ensuring isolated component state.
- **Standard Cypress commands** work immediately after mounting, allowing you to query and interact with components as if in a real application.
- **Component testing mode** is launched via `cypress open --component` or the `cy:open` script defined in [`npm/react/package.json`](https://github.com/cypress-io/cypress/blob/main/npm/react/package.json).

## Frequently Asked Questions

### Can Cypress test React components without running a full application?

Yes. Cypress Component Testing mounts individual React components in isolation without requiring a running development server or built application. The `mount` function from `@cypress/react` renders your component into a detached DOM node within the Cypress test runner, allowing you to test component logic, props, and state independently of your application's routing or data fetching layers.

### What versions of React does Cypress support?

The `@cypress/react` package supports React 18 and newer versions, leveraging the `ReactDOM.createRoot` API introduced in React 18. As defined in [`npm/react/package.json`](https://github.com/cypress-io/cypress/blob/main/npm/react/package.json), React is listed as a peer dependency, meaning you must have React installed in your project. The adapter handles both the legacy and concurrent rendering modes through React 18's client-side hydration APIs.

### How does component testing differ from end-to-end testing in Cypress?

End-to-end (E2E) tests visit full URLs and test complete user flows through your application, while component tests focus on individual React components in isolation. Component tests use the `mount` command instead of `cy.visit()`, run faster because they don't require server infrastructure, and allow you to pass props directly to test specific component states. Both test types use the same Cypress commands (`cy.get`, `cy.click`, etc.) and run in the same browser-based test runner.

### Do I need to install `@cypress/react` separately?

No separate installation is required for typical use cases. The `@cypress/react` adapter is bundled with the main Cypress CLI when you install Cypress. However, you must ensure React is installed in your project as a peer dependency, as declared in [`npm/react/package.json`](https://github.com/cypress-io/cypress/blob/main/npm/react/package.json). The adapter automatically wires itself into the component testing runner when you execute the `cy:open` or `cy:run` scripts.