---
id: api/commands/exec
title: exec | Cypress Documentation
description: Execute a system command in Cypress.
section: api
source_path: docs/api/commands/exec.mdx
version: e6988a974973e9090ce70406c38cb2b9e0eac9fa
updated_at: '2026-05-15T15:50:22.536Z'
---
# 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 [Learn about subject management](/llm/markdown/app/core-concepts/introduction-to-cypress.md#Subject-Management)

`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 finishcy.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 [Learn about chaining commands](/llm/markdown/app/core-concepts/introduction-to-cypress.md#Chains-of-Commands)

*   `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 [Learn about assertions](/llm/markdown/app/core-concepts/introduction-to-cypress.md#Assertions)

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

### Timeouts [Learn about timeouts](/llm/markdown/app/core-concepts/introduction-to-cypress.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.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)
