# How Cypress Component Testing Integrates with React, Vue, Angular, and Svelte

> Discover how Cypress component testing seamlessly integrates with React, Vue, Angular, and Svelte using a unified cy.mount interface. Streamline your component testing workflow.

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

---

**Cypress component testing integrates with React, Vue, Angular, and Svelte through framework-specific adapters that wrap each library's native rendering APIs into a unified `cy.mount` interface.**

Cypress provides dedicated npm packages for component testing across major JavaScript frameworks. According to the cypress-io/cypress source code, each adapter lives under the `npm/` directory and exports a `mount` function that bridges the framework's internal rendering mechanisms with Cypress's command chain.

## Framework-Specific Adapters

Each framework adapter implements a consistent pattern while using the library's native testing APIs under the hood.

### React Adapter

The React adapter ([`npm/react/src/mount.ts`](https://github.com/cypress-io/cypress/blob/main/npm/react/src/mount.ts)) bootstraps components using `ReactDOM.render` (or `createRoot` in React 18+). It wraps the rendered output in a `Cypress.ReactWrapper` object that exposes the component instance to Cypress commands.

The adapter handles JSX transformation and automatically attaches the component to a temporary DOM node (`<div id="cypress-root">`) within the test runner iframe. After each test, it unmounts the component and cleans up the DOM, ensuring test isolation.

### Vue Adapter

In [`npm/vue/src/index.ts`](https://github.com/cypress-io/cypress/blob/main/npm/vue/src/index.ts), the Vue adapter delegates to `@vue/test-utils` and its `mount` helper. It supports both Vue 2 and Vue 3 by detecting the version and applying the appropriate mounting strategy.

The adapter accepts standard Vue Test Utils options (like `props`, `global`, and `slots`) and wraps the result in a `Cypress.VueWrapper`. This wrapper exposes Vue-specific methods such as `vm` (the component instance) while remaining compatible with standard Cypress queries like `cy.get()` and `cy.contains()`.

### Angular Adapter

The Angular implementation in [`npm/angular/src/mount.ts`](https://github.com/cypress-io/cypress/blob/main/npm/angular/src/mount.ts) uses Angular's `TestBed` to compile a testing module and create a component fixture. Unlike React or Vue, Angular requires explicit dependency injection setup, so the adapter accepts a `TestBed` configuration object alongside the component class.

It creates a `Cypress.AngularWrapper` that holds the component fixture, allowing you to access the component instance via `wrapper.component` and trigger change detection manually when needed.

### Svelte Adapter

For Svelte, the adapter in [`npm/svelte/src/mount.ts`](https://github.com/cypress-io/cypress/blob/main/npm/svelte/src/mount.ts) instantiates components using the native Svelte component constructor: `new Component({ target, props })`. It mounts the component to the Cypress-controlled DOM element and creates a `Cypress.SvelteWrapper` that maintains a reference to the component instance.

The Svelte adapter handles both prop passing and event forwarding, ensuring that reactive updates flow correctly through the component tree during test execution.

## Shared Mount Utilities

All adapters rely on [`npm/mount-utils/src/index.ts`](https://github.com/cypress-io/cypress/blob/main/npm/mount-utils/src/index.ts), a common library that supplies helpers for DOM attachment, logging, and cleanup. This shared infrastructure ensures consistent behavior across frameworks while allowing each adapter to focus on framework-specific rendering logic.

The mount-utils package handles:
- Attaching the temporary DOM container to the test runner iframe
- Providing a stable `unmount` function that works across all frameworks
- Propagating rendering errors to Cypress's command log
- Supporting re-mounting when `cy.mount` is called multiple times in the same test

## How the Mount Command Works

When you call `cy.mount(<Component />)`, the execution flow follows this pattern:

1. The framework-specific adapter receives the component and options
2. It calls the library's native render API (e.g., `ReactDOM.render`, `TestBed.createComponent`, or `new SvelteComponent`)
3. It wraps the rendered result in a framework-specific wrapper object (`Cypress.ReactWrapper`, `Cypress.VueWrapper`, etc.)
4. It stores the wrapper on the global `Cypress` object and registers cleanup hooks
5. It returns the wrapper so you can chain Cypress commands immediately

Because the wrapper is stored globally, Cypress can automatically clean up the component after each test, preventing state leakage between tests.

## Installation and Setup

Each adapter is published as a separate npm package under the `@cypress` scope. Install only the adapters you need for your project:

```bash
npm install --save-dev @cypress/react   # React

npm install --save-dev @cypress/vue     # Vue

npm install --save-dev @cypress/angular # Angular

npm install --save-dev @cypress/svelte  # Svelte

```

After installation, import the `mount` function in your test files. The adapters automatically register `cy.mount` as a global Cypress command, so no additional configuration is required in your [`cypress.config.js`](https://github.com/cypress-io/cypress/blob/main/cypress.config.js) or [`cypress.config.ts`](https://github.com/cypress-io/cypress/blob/main/cypress.config.ts).

## Code Examples by Framework

The following examples demonstrate the consistent API across all frameworks. Each uses `cy.mount` followed by standard Cypress assertions.

### React Component Test

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

describe('Counter', () => {
  it('increments when clicked', () => {
    mount(<Counter initialCount={0} />)
    cy.contains('Count: 0')
    cy.get('button').click()
    cy.contains('Count: 1')
  })
})

```

### Vue Component Test

```ts
// cypress/component/HelloWorld.cy.ts
import { mount } from '@cypress/vue'
import HelloWorld from '../../src/HelloWorld.vue'

describe('HelloWorld', () => {
  it('renders props correctly', () => {
    mount(HelloWorld, { 
      props: { msg: 'Hello from Cypress' } 
    })
    cy.contains('Hello from Cypress')
  })
})

```

### Angular Component Test

```ts
// cypress/component/app.component.cy.ts
import { mount } from '@cypress/angular'
import { AppComponent } from '../../src/app/app.component'

describe('AppComponent', () => {
  it('displays the title', () => {
    mount(AppComponent)
    cy.get('h1').should('contain', 'Welcome to Angular')
  })
})

```

### Svelte Component Test

```js
// cypress/component/Counter.cy.js
import { mount } from '@cypress/svelte'
import Counter from '../../src/Counter.svelte'

describe('Counter', () => {
  it('reacts to button clicks', () => {
    mount(Counter, { props: { initial: 0 } })
    cy.contains('Count: 0')
    cy.get('button').click()
    cy.contains('Count: 1')
  })
})

```

## Summary

Cypress component testing provides seamless integration with React, Vue, Angular, and Svelte through architectural patterns that balance framework-specific needs with a consistent developer experience:

- **Framework adapters** in `npm/<framework>/` wrap native rendering APIs (ReactDOM, Vue Test Utils, Angular TestBed, Svelte constructors) into a unified `mount` function
- **Cypress wrappers** (`Cypress.ReactWrapper`, `Cypress.VueWrapper`, etc.) bridge framework component instances with Cypress command chains
- **Shared mount utilities** ([`npm/mount-utils/src/index.ts`](https://github.com/cypress-io/cypress/blob/main/npm/mount-utils/src/index.ts)) handle DOM attachment, automatic cleanup, and error logging across all frameworks
- **Global `cy.mount` command** becomes available immediately after installing the respective adapter, requiring no additional configuration
- **Automatic isolation** ensures components unmount after each test, preventing state leakage and flaky tests

## Frequently Asked Questions

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

Cypress component testing mounts individual components in isolation using the actual framework rendering engine, while end-to-end testing drives a full application through a browser. Component tests run faster, require no server, and focus on component-level behavior, whereas E2E tests verify complete user workflows across multiple pages.

### Can I use the same Cypress commands in component tests that I use in E2E tests?

Yes. After calling `cy.mount()`, you have access to the full Cypress API including `cy.get()`, `cy.contains()`, `cy.click()`, and custom commands. The framework adapters ensure that queried elements reference the mounted component's DOM subtree, maintaining the same query behavior as E2E tests.

### Do I need to configure a development server for Cypress component testing?

No. Cypress component testing runs your components directly in the browser without requiring a separate development server or build step during test execution. The framework adapters handle the compilation and mounting internally, though you need the respective adapter package installed (`@cypress/react`, `@cypress/vue`, etc.) for your framework.

### How does the automatic cleanup work between tests?

Each adapter registers an `afterEach` hook that calls the framework-specific unmount function. This removes the component from the DOM and destroys the wrapper instance stored on `Cypress`. The shared [`npm/mount-utils/src/index.ts`](https://github.com/cypress-io/cypress/blob/main/npm/mount-utils/src/index.ts) library coordinates this cleanup, ensuring that DOM nodes and component state do not persist between tests, which prevents cross-test contamination.