# How to Configure Cypress for Different Environments: A Complete Guide to Multi-Env Testing

> Learn to configure Cypress for different environments using configurations blocks CLI flags and environment variables. Master multi-env testing with this complete guide.

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

---

**Cypress supports environment-specific testing through a combination of `cypress.config.{js|ts}` files with named `configurations` blocks, CLI flags, `CYPRESS_`-prefixed environment variables, and optional [`cypress.env.json`](https://github.com/cypress-io/cypress/blob/main/cypress.env.json) files.**

Cypress provides a flexible configuration system that lets you tailor test runs for development, staging, production, or any custom environment without maintaining separate config files. By leveraging the `defineConfig` helper and the `configurations` key, you can maintain a single source-controlled [`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) while targeting multiple deployment targets.

## Using Named Configurations for Multiple Environments

The most robust way to configure Cypress for different environments is to define named configuration blocks inside your main config file. When you export your configuration using `defineConfig`, you can include a top-level `configurations` object containing environment-specific overrides.

In [`system-tests/projects/config-with-ts/cypress.config.ts`](https://github.com/cypress-io/cypress/blob/main/system-tests/projects/config-with-ts/cypress.config.ts), the test suite demonstrates how to structure a TypeScript config file that supports multiple environments:

```typescript
// cypress.config.ts
import { defineConfig } from 'cypress'

export default defineConfig({
  // Global defaults applied to all environments
  pageLoadTimeout: 60000,
  screenshotsFolder: 'cypress/screenshots',
  video: true,

  // Per-environment overrides
  configurations: {
    dev: {
      baseUrl: 'http://localhost:3000',
      env: {
        API_URL: 'http://localhost:4000/api',
      },
    },
    staging: {
      baseUrl: 'https://staging.example.com',
      env: {
        API_URL: 'https://staging.api.example.com',
      },
    },
    prod: {
      baseUrl: 'https://app.example.com',
      env: {
        API_URL: 'https://api.example.com',
      },
    },
  },

  e2e: {
    setupNodeEvents(on, config) {
      // Environment-specific Node event handlers
      return config
    },
  },
})

```

When you select a configuration, Cypress merges the chosen block into the base config, layer by layer. This pattern keeps all environment definitions in one place while avoiding duplication of shared settings like timeouts or folder paths.

## Switching Environments via CLI and Environment Variables

Cypress offers two primary mechanisms for selecting which named configuration to use at runtime: CLI flags and environment variables.

**CLI flag method** (ideal for local testing):

```bash
cypress run --config-file cypress.config.ts --config configurations=staging

```

**Environment variable method** (preferred for CI/CD pipelines):

```bash
CYPRESS_configurations=prod cypress run

```

Any configuration key can be overridden via the `CYPRESS_` prefix. For example, `CYPRESS_baseUrl=https://staging.example.com` temporarily replaces the `baseUrl` defined in your config file. According to the application lifecycle documentation in [`guides/app-lifecycle.md`](https://github.com/cypress-io/cypress/blob/main/guides/app-lifecycle.md), these environment variables are processed before the config file is evaluated, ensuring they take precedence over file-based settings.

You can also pass arbitrary config values directly:

```bash
cypress run --config baseUrl=https://staging.example.com,viewportWidth=1280

```

## Managing Environment Variables and Secrets

For values that change per environment but should not be hardcoded—such as API tokens or feature flags—Cypress supports a [`cypress.env.json`](https://github.com/cypress-io/cypress/blob/main/cypress.env.json) file placed in your project root. This JSON file loads before the config file evaluation, making its keys available during configuration setup.

```json
// cypress.env.json
{
  "API_TOKEN": "abc123",
  "FEATURE_X_ENABLED": true
}

```

As implemented in the Cypress monorepo, the legacy `Cypress.env()` API is being phased out in favor of the newer `Cypress.expose()` API. To enforce this migration, set `allowCypressEnv: false` in your config:

```typescript
export default defineConfig({
  allowCypressEnv: false,
  expose: {
    API_ENDPOINT: 'https://api.example.com',
    FEATURE_FLAG: true,
  },
})

```

The `expose` object makes these values available to your tests while keeping them out of the browser's global scope until explicitly requested. This approach is documented in [`cli/CHANGELOG.md`](https://github.com/cypress-io/cypress/blob/main/cli/CHANGELOG.md) as the forward-compatible strategy for environment variable management.

## Separating E2E and Component Testing Configurations

Modern Cypress setups often run both end-to-end (E2E) and component tests against different targets. The same `cypress.config` file can contain separate `e2e` and `component` blocks, each with distinct `baseUrl` values and support files.

```typescript
export default defineConfig({
  configurations: {
    dev: {
      baseUrl: 'http://localhost:3000',
    },
  },
  
  e2e: {
    baseUrl: 'https://staging.example.com', // Falls back to this if no config selected
    supportFile: 'cypress/support/e2e.ts',
  },
  
  component: {
    devServer: {
      framework: 'react',
      bundler: 'vite',
    },
    supportFile: 'cypress/support/component.ts',
  },
})

```

This structure allows component tests to run against a local Vite or Webpack dev server while E2E tests hit a fully deployed staging environment, all controlled from the same configuration source.

## Configuration Schema and Validation

The canonical configuration schema is defined in [`packages/config/README.md`](https://github.com/cypress-io/cypress/blob/main/packages/config/README.md), which documents validation logic used across the Cypress monorepo. All supported configuration options—including `baseUrl`, `env`, `allowCypressEnv`, and `configurations`—are typed in [`cli/types/cypress.d.ts`](https://github.com/cypress-io/cypress/blob/main/cli/types/cypress.d.ts).

When troubleshooting configuration issues, reference these source files to verify:
- Valid keys within `defineConfig`
- Type requirements for the `configurations` object
- Merge behavior when combining CLI overrides with file-based settings

## Summary

- **Named configurations**: Use the `configurations` key inside `defineConfig` to create per-environment blocks for dev, staging, and production.
- **Runtime selection**: Switch environments using `--config configurations=name` CLI flags or `CYPRESS_configurations=name` environment variables.
- **Variable management**: Store sensitive values in [`cypress.env.json`](https://github.com/cypress-io/cypress/blob/main/cypress.env.json) or use the `expose` config key with `allowCypressEnv: false` for modern variable handling.
- **Test type separation**: Define separate blocks for `e2e` and `component` testing within the same file to target different servers.
- **Source references**: Configuration behavior is implemented in [`system-tests/projects/config-with-ts/cypress.config.ts`](https://github.com/cypress-io/cypress/blob/main/system-tests/projects/config-with-ts/cypress.config.ts) and documented in [`packages/config/README.md`](https://github.com/cypress-io/cypress/blob/main/packages/config/README.md).

## Frequently Asked Questions

### How do I run Cypress against different URLs without changing the config file?

Use the `CYPRESS_baseUrl` environment variable or the `--config baseUrl=<url>` CLI flag. These overrides take precedence over values in `cypress.config.{js|ts}`, allowing you to target staging or production servers from the same configuration.

### Can I disable the old `Cypress.env()` API?

Yes. Set `allowCypressEnv: false` in your `defineConfig` export. This forces your team to use the `expose` configuration object instead, which provides better type safety and is the recommended path forward according to the Cypress CLI changelog.

### What is the difference between [`cypress.env.json`](https://github.com/cypress-io/cypress/blob/main/cypress.env.json) and the `configurations` key?

[`cypress.env.json`](https://github.com/cypress-io/cypress/blob/main/cypress.env.json) loads environment variables before config evaluation and is ideal for secrets or local overrides. The `configurations` key lives inside your main config file and defines complete environment profiles (including `baseUrl`, timeouts, and nested `env` objects) that you select via CLI flags.

### How do I configure different settings for component tests versus E2E tests?

Define separate `e2e` and `component` blocks in your `cypress.config` file. Each block can specify its own `baseUrl`, `supportFile`, and `setupNodeEvents` function, allowing component tests to target a dev server while E2E tests hit a deployed application.