# Cypress Commands: Complete Guide to Built-in API and Custom Commands

> Discover Cypress commands, the asynchronous API for efficient test automation. Learn to use built-in and custom commands to streamline your testing workflow.

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

---

**Cypress commands are asynchronous methods attached to the global `cy` object that execute in a deterministic command queue, enabling everything from DOM traversal to custom test utilities.**

The **Cypress commands** API forms the backbone of the Cypress testing framework. In the `cypress-io/cypress` repository, these commands are implemented as a sophisticated queue-based system that handles retries, timeouts, and automatic waiting. Understanding how to leverage both built-in and custom commands is essential for writing reliable end-to-end and component tests.

## What Are Cypress Commands?

Cypress commands are the core API methods that drive test execution. They are attached to the global `cy` object and include methods like `cy.visit()`, `cy.get()`, and `cy.request()`. When a test calls a command, Cypress places it in an internal command queue; the test runner processes this queue step-by-step, handling automatic retries and timeouts.

Commands execute **asynchronously** but appear synchronous in your code. This deterministic queue ensures that each command waits for the previous one to complete before executing, with built-in retry logic that waits for elements to become actionable.

## How Cypress Commands Work

### Command Queue and Asynchronous Execution

The command queue is the architectural foundation of Cypress. Located in the driver package, the scheduler manages command chaining, resolves promises, and injects automatic waits between operations. The validation logic for command definitions resides in [`packages/driver/src/cypress/error_messages.ts`](https://github.com/cypress-io/cypress/blob/main/packages/driver/src/cypress/error_messages.ts), which protects against duplicate or reserved command names.

When you write `cy.get('.button').click()`, Cypress does not execute these immediately. Instead, it queues both commands, then processes them sequentially with automatic retry-on-failure logic.

### Built-in Commands

Built-in commands are implemented in the driver package and expose high-level actions such as DOM traversal, network requests, and filesystem interactions. These commands form the standard API that every Cypress test uses.

```typescript
// Visit a page and assert the title
cy.visit('/login')
cy.title().should('eq', 'Login – MyApp')

```

### Custom Commands

Users extend the API via `Cypress.Commands.add(name, fn)` or `Cypress.Commands.addQuery()`. Custom commands are typically defined in support files ([`cypress/support/commands.ts`](https://github.com/cypress-io/cypress/blob/main/cypress/support/commands.ts) or similar), which load before test files execute. This registration process places the new command in the same registry used by core commands, ensuring it participates fully in chaining and retry mechanics.

## Using Built-in Cypress Commands

Built-in commands are called directly on the `cy` object and return chainable objects that allow further commands to be appended.

```typescript
// Chain built-in commands for comprehensive testing
cy.visit('/dashboard')
cy.get('[data-testid="user-menu"]').click()
cy.url().should('include', '/profile')

```

Each command receives the subject from the previous command unless explicitly configured otherwise. This subject inheritance enables expressive, readable test flows without manual variable management.

## Creating Custom Commands

### Simple Custom Commands

Define reusable test utilities by adding commands to the global `cy` object. The [`packages/frontend-shared/cypress/support/component.ts`](https://github.com/cypress-io/cypress/blob/main/packages/frontend-shared/cypress/support/component.ts) file demonstrates this pattern by registering a `mount` command for component testing.

```typescript
// packages/frontend-shared/cypress/support/component.ts
Cypress.Commands.add('mount', mount)

```

Usage in a spec file:

```typescript
import { MyButton } from './MyButton.vue'

cy.mount(MyButton).get('button').should('contain.text', 'Click me')

```

### Commands with Previous Subject

Use the `prevSubject` option to create commands that act on an existing subject, such as a DOM element. The [`packages/launchpad/cypress/e2e/support/dropFileWithPath.ts`](https://github.com/cypress-io/cypress/blob/main/packages/launchpad/cypress/e2e/support/dropFileWithPath.ts) file illustrates this pattern.

```typescript
// packages/launchpad/cypress/e2e/support/dropFileWithPath.ts
Cypress.Commands.add(
  'dropFileWithPath',
  { prevSubject: 'element' },
  (subject, filePath) => {
    // Implementation triggers drag-and-drop on the element
    return cy.wrap(subject).trigger('drop', { dataTransfer: new DataTransfer() })
  }
)

```

Usage in a test:

```typescript
cy.get('#drop-zone')
  .dropFileWithPath('cypress/fixtures/sample.png')
  .should('have.class', 'has-file')

```

Setting `prevSubject: 'element'` ensures the command only executes when chained off an element query, receiving the subject as the first argument.

### Custom Queries

Add commands that return computed values rather than chainable objects using `Cypress.Commands.addQuery()`. These are useful for extracting data from the application under test.

```typescript
Cypress.Commands.addQuery('getAll', () => {
  return cy.window().then(win => Object.keys(win))
})

```

Usage:

```typescript
cy.getAll().should('include', 'myGlobalVar')

```

### Overwriting Existing Commands

Safely modify existing command behavior using `Cypress.Commands.overwrite()`. This approach is guarded internally to prevent accidental breaking changes.

```typescript
Cypress.Commands.overwrite('click', (originalFn, element, options) => {
  cy.log('Custom click logging')
  return originalFn(element, options)
})

```

## Key Implementation Files

Understanding where Cypress commands are defined helps when debugging or extending the framework:

- **[`packages/driver/src/cypress/error_messages.ts`](https://github.com/cypress-io/cypress/blob/main/packages/driver/src/cypress/error_messages.ts)** – Contains validation logic that prevents duplicate command names and reserved keyword conflicts.
- **[`packages/frontend-shared/cypress/support/component.ts`](https://github.com/cypress-io/cypress/blob/main/packages/frontend-shared/cypress/support/component.ts)** – Registers the `mount` command used by component-testing adapters.
- **[`packages/launchpad/cypress/e2e/support/dropFileWithPath.ts`](https://github.com/cypress-io/cypress/blob/main/packages/launchpad/cypress/e2e/support/dropFileWithPath.ts)** – Example of a custom command utilizing `prevSubject`.
- **[`packages/driver/cypress/support/utils.ts`](https://github.com/cypress-io/cypress/blob/main/packages/driver/cypress/support/utils.ts)** – Registers internal privileged commands for framework operations.
- **[`packages/frontend-shared/cypress/support/e2e.ts`](https://github.com/cypress-io/cypress/blob/main/packages/frontend-shared/cypress/support/e2e.ts)** – Collection of higher-level end-to-end helper commands like `scaffoldProject` and `loginUser`.

## Summary

- **Cypress commands** are asynchronous methods on the `cy` object that execute in a deterministic queue with automatic retries and timeouts.
- **Built-in commands** cover DOM traversal, network requests, and assertions, implemented in the driver package.
- **Custom commands** extend the API via `Cypress.Commands.add()` and participate in the same retry and chaining logic as core commands.
- Use **`prevSubject`** to create commands that operate on existing DOM elements or other subjects.
- **`Cypress.Commands.addQuery()`** creates commands that return values rather than chainable objects.
- **`Cypress.Commands.overwrite()`** allows safe modification of existing command behavior.

## Frequently Asked Questions

### What is the difference between `Cypress.Commands.add()` and `Cypress.Commands.addQuery()`?

`Cypress.Commands.add()` creates standard commands that return chainable objects and can be used for actions like clicking or typing. `Cypress.Commands.addQuery()` creates commands that return a computed value and do not chain further, making them suitable for extracting data from the application state.

### How does Cypress handle asynchronous command execution?

Cypress maintains an internal command queue that processes commands sequentially. When you call `cy.get()`, the command is queued rather than executed immediately. The test runner processes the queue step-by-step, ensuring each command completes before the next begins, with built-in retry logic for handling timing issues.

### Can I override built-in Cypress commands?

Yes, use `Cypress.Commands.overwrite('commandName', (originalFn, ...args) => { ... })` to modify existing command behavior. This is guarded by validation in [`packages/driver/src/cypress/error_messages.ts`](https://github.com/cypress-io/cypress/blob/main/packages/driver/src/cypress/error_messages.ts) to prevent accidental breaking changes. Always call `originalFn()` within your overwrite to maintain core functionality.

### Where should I define custom commands?

Define custom commands in support files located in `cypress/support/`, typically [`commands.ts`](https://github.com/cypress-io/cypress/blob/main/commands.ts) or [`e2e.ts`](https://github.com/cypress-io/cypress/blob/main/e2e.ts). These files load before test files execute, ensuring your custom commands are registered in the global `cy` object before specs run. This pattern is demonstrated in [`packages/frontend-shared/cypress/support/component.ts`](https://github.com/cypress-io/cypress/blob/main/packages/frontend-shared/cypress/support/component.ts) for component testing utilities.