---
id: api/commands/exec
title: 'cy.exec() [Deprecated]'
description: 'Deprecated: Execute a system command in Cypress.'
section: api
source_path: docs/api/commands/exec.mdx
version: d223bf4295fb01e06a336e4f4a04c9f08a56d812
updated_at: '2026-08-21T02:10:32.980Z'
---
# cy.exec() [Deprecated]

**Deprecated**

`cy.exec()` was deprecated in Cypress `15.21.0` and will be removed in a future major version. The [`execTimeout`](/llm/markdown/app/references/configuration.md#Timeouts) configuration option is deprecated along with it.

Use [`cy.task()`](/llm/markdown/api/commands/task.md) instead, which runs in Node without depending on the operating system, shell, or terminal of the machine running Cypress. See [Run an external command or CLI](/llm/markdown/api/commands/task.md#Run-an-external-command-or-CLI) for tasks that shell out to a non-Node tool.

# exec

Execute a system command.

**Anti-Pattern**

Don't try to start a web server from `cy.exec()`.

Read about [best practices](/llm/markdown/app/core-concepts/best-practices.md#Web-Servers) here.

## Syntax

```
cy.exec(command)
cy.exec(command, options)
```

### Usage

**Correct Usage**

```
cy.exec('npm run build')
```

### Arguments

**command _(String)_**

The system command to be executed from the project root (the directory that contains the [Cypress configuration file](/llm/markdown/app/references/configuration.md)).

**options _(Object)_**

Pass in an options object to change the default behavior of `cy.exec()`.

| Option | Default | Description |
| --- | --- | --- |
| `log` | `true` | Displays the command in the [Command log](/llm/markdown/app/core-concepts/open-mode.md#Command-Log) |
| `env` | `{}` | Object of environment variables to set before the command executes (e.g. `{USERNAME: 'johndoe'}`). Will be merged with existing system environment variables |
| `failOnNonZeroExit` | `true` | whether to fail if the command exits with a non-zero code |
| `timeout` | [`execTimeout`](/llm/markdown/app/references/configuration.md#Timeouts) | Time to wait for `cy.exec()` to resolve before [timing out](#Timeouts) |

### Yields

`cy.exec()` yields an object with the following properties:

*   `exitCode`
*   `stdout`
*   `stderr`

## Examples

### Command

`cy.exec()` provides an escape hatch for running arbitrary system commands, so you can take actions necessary for your test outside the scope of Cypress. This is great for:

*   Running build scripts
*   Seeding your test database
*   Starting processes
*   Killing processes

#### Run a build command

```
cy.exec('npm run build').then((result) => {
  // yields the 'result' object
  // {
  //   exitCode: 0,
  //   stdout: "Files successfully built",
  //   stderr: ""
  // }
})
```

#### Seed the database and assert it was successful

```
cy.exec('rake db:seed').its('exitCode').should('eq', 0)
```

#### Run an arbitrary script and assert its output

```
cy.exec('npm run my-script')
  .its('stdout')
  .should('contain', 'Done running the script')
```

#### Write to a file to create a fixture from response body

```
cy.intercept('POST', '/comments').as('postComment')
cy.get('.add-comment').click()
cy.wait('@postComment').then(({ response }) => {
  cy.exec(
    `echo ${JSON.stringify(response.body)} >cypress/fixtures/comment.json`
  )
  cy.fixture('comment.json').should('deep.eq', response.body)
})
```

### Options

#### Change the timeout

You can increase the time allowed to execute the command, although _we don't recommend executing commands that take a long time to exit_.

Cypress will _not_ continue running any other commands until `cy.exec()` has finished, so a long-running command will drastically slow down your test cycle.

```
// will fail if script takes longer than 20 seconds to finish
cy.exec('npm run build', { timeout: 20000 })
```

#### Choose to not fail on non-zero exit and assert on code and stderr

```
cy.exec('man bear pig', { failOnNonZeroExit: false }).then((result) => {
  expect(result.exitCode).to.eq(1)
  expect(result.stderr).to.contain('No manual entry for bear')
})
```

#### Specify system environment variables

```
cy.exec('echo $USERNAME', { env: { USERNAME: 'johndoe' } })
  .its('stdout')
  .should('contain', 'johndoe')
```

## Notes

### Commands Must Exit

#### Commands that do not exit are not supported

`cy.exec()` does not support commands that don't exit, such as:

*   Starting a `rails server`
*   A task that runs a watch
*   Any process that needs to be manually interrupted to stop

A command must exit within the `execTimeout` or Cypress will kill the command's process and fail the current test.

### Reset timeout via `Cypress.config()`

You can change the timeout of `cy.exec()` for the remainder of the tests by setting the new values for `execTimeout` within [Cypress.config()](/llm/markdown/api/cypress-api/config.md).

```
Cypress.config('execTimeout', 30000)
Cypress.config('execTimeout') // => 30000
```

### Set timeout in the test configuration

You can configure the `cy.exec()` timeout within a suite or test by passing the new configuration value within the [test configuration](/llm/markdown/app/references/configuration.md#Test-Configuration).

This will set the timeout throughout the duration of the tests, then return it to the default `execTimeout` when complete.

```
describe('has data available from database', { execTimeout: 90000 }, () => {
  before(() => {
    cy.exec('rake db:seed')
  })

  // tests

  after(() => {
    cy.exec('rake db:reset')
  })
})
```

## Rules

### Requirements

*   `cy.exec()` requires being chained off of `cy`.
*   `cy.exec()` requires the executed system command to eventually exit.
*   `cy.exec()` requires that the exit code be `0` when `failOnNonZeroExit` is `true`.

### Assertions

*   `cy.exec()` will only run assertions you have chained once, and will not [retry](/llm/markdown/app/core-concepts/retry-ability.md).

### Timeouts

*   `cy.exec()` can time out waiting for the system command to exist.

## Command Log

**_List the contents of your package.json file_**

```
if (Cypress.platform === 'win32') {
  cy.exec('type package.json').its('stderr').should('be.empty')
} else {
  cy.exec('cat package.json').its('stderr').should('be.empty')
}
```

The command above will display in the Command Log as:

When clicking on the `exec` command within the command log, the console outputs the following:

## History

| Version | Changes |
| --- | --- |
| [15.21.0](/llm/markdown/app/references/changelog.md#15-21-0) | `cy.exec()` command and `execTimeout` deprecated |
| [15.0.0](/llm/markdown/app/references/changelog.md#15-0-0) | Renamed property `code` to `exitCode` |

## See also

*   [`cy.readFile()`](/llm/markdown/api/commands/readfile.md)
*   [`cy.request()`](/llm/markdown/api/commands/request.md)
*   [`cy.task()`](/llm/markdown/api/commands/task.md)
*   [`cy.writeFile()`](/llm/markdown/api/commands/writefile.md)
