---
id: app/references/module-api
title: 'Module API: How to run Cypress via Node.js'
description: >-
  Require Cypress as a node module from your application under test and run
  Cypress via Node.js.
section: app
source_path: docs/app/references/module-api.mdx
version: e6988a974973e9090ce70406c38cb2b9e0eac9fa
updated_at: '2026-05-15T15:50:22.536Z'
---
# Module API

You can require Cypress as a node module from your application under test and run Cypress via Node.js. This can be useful when you want access to the test results directly after the run. With this workflow, for example, you can:

*   Send a notification about failing tests with included screenshot images
*   Rerun a single failing spec file
*   Kick off other builds or scripts

**Yarn Plug'n'Play**

To run Cypress via Node.js in a [Yarn Plug'n'Play](https://yarnpkg.com/features/pnp) environment, use [yarn node](https://yarnpkg.com/cli/node) instead of [node](https://nodejs.org/en/learn/command-line/run-nodejs-scripts-from-the-command-line).

## `cypress.run()`

Runs Cypress tests via Node.js and resolve with all test results. See the [Cypress Module API recipe](https://github.com/cypress-io/cypress-example-recipes#fundamentals).

```
// e2e-run-tests.jsconst cypress = require('cypress')cypress.run({  reporter: 'junit',  browser: 'chrome',  config: {    baseUrl: 'http://localhost:8080',    video: true,  },  env: {    apiKey: 'secret-key-12345',  },  expose: {    apiVersion: 'v2',  },})
```

You can then run Cypress by running the following in your terminal or an npm script:

```
node e2e-run-tests.js
```

### Options

Just like the [Command Line options](/llm/markdown/app/references/command-line.md) for `cypress run`, you can pass options that modify how Cypress runs.

| Option | Type | Description |
| --- | --- | --- |
| `autoCancelAfterFailures` | _number_ | _false_ | Specify the number of failures to cancel a run being recorded to the Cloud or `false` to disable auto-cancellation. |
| `browser` | _string_ | Specify different browser to run tests in, either by name or by filesystem path |
| `ciBuildId` | _string_ | Specify a unique identifier for a run to enable [grouping](/llm/markdown/cloud/features/smart-orchestration/parallelization.md#Grouping-test-runs) or [parallelization](/llm/markdown/cloud/features/smart-orchestration/parallelization.md) |
| `config` | _object_ | Specify [configuration](/llm/markdown/app/references/configuration.md) |
| `configFile` | _string_ | Path to the [configuration file](/llm/markdown/app/references/configuration.md#Configuration-File) to be used. |
| `env` | _object_ | Specify secret [environment variables](/llm/markdown/app/guides/environment-variables.md) |
| `expose` | _object_ | Specify public [exposed variables](/llm/markdown/api/cypress-api/expose.md) |
| `group` | _string_ | [Group](/llm/markdown/cloud/features/smart-orchestration/parallelization.md#Grouping-test-runs) recorded tests together under a single run |
| `headed` | _boolean_ | Displays the browser instead of running headlessly |
| `headless` | _boolean_ | Hide the browser instead of running headed (default during `cypress run`) |
| `key` | _string_ | Specify your secret record key |
| `exit` | _boolean_ | Whether to close Cypress after all tests run |
| `parallel` | _boolean_ | Run recorded specs in [parallel](/llm/markdown/cloud/features/smart-orchestration/parallelization.md) across multiple machines |
| `port` | _number_ | Override default port |
| `posixExitCodes` | _boolean_ | Exit with a POSIX-compliant exit code rather than the number of failed tests. |
| `project` | _string_ | Path to a specific project |
| `quiet` | _boolean_ | If passed, Cypress output will not be printed to `stdout`. Only output from the configured [Mocha reporter](/llm/markdown/app/tooling/reporters.md) will print. |
| `record` | _boolean_ | Whether to record the test run |
| `reporter` | _string_ | Specify a [Mocha reporter](/llm/markdown/app/tooling/reporters.md) |
| `reporterOptions` | _object_ | Specify [Mocha reporter](/llm/markdown/app/tooling/reporters.md) options |
| `runnerUi` | _boolean_ | Whether to display the Cypress Runner UI. Defaults to `false` when [Test Replay](/llm/markdown/cloud/features/test-replay.md) is enabled. Otherwise defaults to `true`. |
| `slowTestThreshold` | _number_ | Time, in milliseconds, to consider a test "slow" during `cypress run`. A slow test will display in orange text in the default reporter. |
| `spec` | _string_ | Specify the specs to run, see examples below |
| `tag` | _string_ | Identify a run with a tag or tags |
| `testingType` | _string_ | Specify the type of tests to execute; either `e2e` or `component`. Defaults to `e2e` |

### Examples

#### Run a single spec file

Here is an example of programmatically running a spec file. Note that the file path is relative to the current working directory.

```
// e2e-run-tests.jsconst cypress = require('cypress')cypress  .run({    // the path is relative to the current working directory    spec: './cypress/e2e/examples/actions.cy.js',  })  .then((results) => {    console.log(results)  })  .catch((err) => {    console.error(err)  })
```

You can then run Cypress by running the following in your terminal or an npm script:

```
node e2e-run-tests.js
```

#### Run specs using wildcard

You can pass a wildcard pattern to run all matching spec files

```
const cypress = require('cypress')cypress.run({  // the wildcard path is relative to the current working directory  spec: './cypress/e2e/**/api*.js',})
```

#### Programmatically control which browser to run

You can pass a browser option to specify which browser to run tests in so that you can programmatically control which specs to run in each browser.

```
// run 'node cypress-chrome.js'const cypress = require('cypress')cypress.run({  spec: './cypress/e2e/**/chrome-test*.js',  browser: 'chrome',})
```

```
// run 'node cypress-firefox.js'const cypress = require('cypress')cypress.run({  spec: './cypress/e2e/**/firefox-test*.js',  browser: 'firefox',})
```

#### Use modern syntax

If your Node version allows you can use the modern `async / await` syntax to wait for the Promise returned by the `cypress.run` method.

```
const cypress = require('cypress');(async () => {  const results = await cypress.run()  // use the results object})()
```

### Results

`cypress.run()` returns a `Promise` that resolves with an object containing the tests results. A typical run could return something like this:

```
{  "cypressVersion": "3.0.2",  "endedTestsAt": "2018-07-11T17:53:35.675Z",  "browserName": "electron",  "browserPath": "path/to/browser",  "browserVersion": "59.0.3071.115",  "config": {...},  "osName": "darwin",  "osVersion": "14.5.0",  "runs": [{    "error": null,    "reporter": "spec",    "reporterStats": {...},    "spec": {...},    "stats": {      "suites": 1,      "tests": 1,      "passes": 0,      "pending": 0,      "skipped": 0,      "failures": 1,      "startedAt": "2020-08-05T08:38:37.589Z",      "endedAt": "2018-07-11T17:53:35.675Z",      "duration": 1171    },    "screenshots": [{      "name": null,      "takenAt": "2020-08-05T08:52:20.432Z",      "path": "User/janelane/my-app/cypress/screenshots/cy.js/test (failed).png",      "height": 720,      "width": 1280    }],    "tests": [{      "title": [ "test" ],      "state": "failed",      "displayError": "AssertionError: expected true to be false\n' +      '    at Context.eval (...cypress/e2e/cy.js:5:21",      "attempts": [{        "state": "failed",      }],    }],    "video": "User/janelane/my-app/cypress/videos/abc123.mp4"  }],  "runUrl": "https://cloud.cypress.io/projects/def456/runs/12",  "startedTestsAt": "2018-07-11T17:53:35.463Z",  "totalDuration": 212,  "totalFailed": 1,  "totalPassed": 0,  "totalPending": 0,  "totalSkipped": 0,  "totalSuites": 1,  "totalTests": 1,}
```

You can find the TypeScript definition for the results object in the [`cypress/cli/types` folder](https://github.com/cypress-io/cypress/tree/develop/cli/types).

### Handling errors

Even when tests fail or a spec errors, the `Promise` resolves with the test results. If a spec errors, the error message will be in the `runs` array under the `error` field. The `Promise` is only rejected if Cypress cannot run for some reason (for example if a binary has not been installed or it cannot find a module dependency). In that case, the `Promise` will be rejected with a detailed error.

There is a third option - Cypress could run, but the tests could not start for some reason. In that case the resolved value is an object with two fields

```
{  "failures": 1,    // non-zero number  "message": "..."  // error message}
```

In order to handle these possible errors, you can add a `catch` to `cypress.run()`:

```
// e2e-run-tests.jsconst cypress = require('cypress')cypress.run({...}).then(result => {  if (result.failures) {    console.error('Could not execute tests')    console.error(result.message)    process.exit(result.failures)  }  // exit with the number of failed tests as exit code  process.exit(result.totalFailed)}).catch(err => {  console.error(err.message)  process.exit(1)})
```

## `cypress.open()`

Open Cypress tests via Node.js.

```
// e2e-open-tests.jsconst cypress = require('cypress')cypress.open({  config: {    baseUrl: 'http://localhost:8080',  },  env: {    apiKey: 'secret-key-12345',  },  expose: {    apiVersion: 'v2',  },})
```

You can then open Cypress by running the following in your terminal or an npm script:

```
node e2e-open-tests.js
```

### Options

Just like the [Command Line options](/llm/markdown/app/references/command-line.md), you can pass options that modify how Cypress runs.

| Option | Type | Description |
| --- | --- | --- |
| `browser` | _string_ | Specify a filesystem path to a custom browser |
| `config` | _object_ | Specify [configuration](/llm/markdown/app/references/configuration.md) |
| `configFile` | _string_ | Path to the [configuration file](/llm/markdown/app/references/configuration.md#Configuration-File) to be used. |
| `detached` | _boolean_ | Open Cypress in detached mode |
| `env` | _object_ | Specify secret [environment variables](/llm/markdown/app/guides/environment-variables.md) |
| `expose` | _object_ | Specify public [exposed variables](/llm/markdown/api/cypress-api/expose.md) |
| `global` | _boolean_ | Run in global mode |
| `port` | _number_ | Override default port |
| `project` | _string_ | Path to a specific project |
| `testingType` | _string_ | Specify the type of tests to execute; either `e2e` or `component`. Defaults to `e2e` |

### Example

```
// e2e-open-tests.jsconst cypress = require('cypress')cypress.open({})
```

You can then open Cypress by running the following in your terminal or an npm script:

```
node e2e-open-tests.js
```

## `cypress.cli`

### `parseRunArguments()`

If you are writing a tool that wraps around the `cypress.run()` command, you might want to parse user-supplied command line arguments using the same logic as `cypress run` uses. In that case, you can use the included `parseRunArguments` function.

```
// wrapper.jsconst cypress = require('cypress')const runOptions = await cypress.cli.parseRunArguments(process.argv.slice(2))const results = await cypress.run(runOptions)// process the "cypress.run()" results
```

An example use running from your terminal could be:

```
node ./wrapper cypress run --browser chrome --config ...
```

**Note:** the arguments passed to `parseRunArguments` should start with `cypress run`.

## History

| Version | Changes |
| --- | --- |
| [15.10.0](/llm/markdown/app/references/changelog.md#15-10-0) | Added `expose` configuration option. |
| [15.4.0](/llm/markdown/app/references/changelog.md#15-4-0) | Added `posixExitCodes` to run options. |
| [12.6.0](/llm/markdown/app/references/changelog.md#12-6-0) | Added `autoCancelAfterFailures` to run options. |
| [10.0.0](/llm/markdown/app/references/changelog.md#10-0-0) | `slowTestThreshold` is now scoped to each testing type. |
| [8.7.0](/llm/markdown/app/references/changelog.md#8-7-0) | Added `slowTestThreshold` configuration option. |
| [7.3.0](/llm/markdown/app/references/changelog.md#7-3-0) | Added `testingType` configuration option. |
| [5.0.0](/llm/markdown/app/references/changelog.md#5-0-0) | Test results returned from `cypress.run()` changed. |
| [4.11.0](/llm/markdown/app/references/changelog.md#4-11-0) | Added `cypress.cli` with `parseRunArguments` function. |
| [4.9.0](/llm/markdown/app/references/changelog.md#4-9-0) | Added `quiet` option to `cypress.run()` |
