How to Configure Cypress for Different Environments: A Complete Guide to Multi-Env Testing
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 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 or 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, the test suite demonstrates how to structure a TypeScript config file that supports multiple environments:
// 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):
cypress run --config-file cypress.config.ts --config configurations=staging
Environment variable method (preferred for CI/CD pipelines):
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, 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:
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 file placed in your project root. This JSON file loads before the config file evaluation, making its keys available during configuration setup.
// 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:
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 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.
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, 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.
When troubleshooting configuration issues, reference these source files to verify:
- Valid keys within
defineConfig - Type requirements for the
configurationsobject - Merge behavior when combining CLI overrides with file-based settings
Summary
- Named configurations: Use the
configurationskey insidedefineConfigto create per-environment blocks for dev, staging, and production. - Runtime selection: Switch environments using
--config configurations=nameCLI flags orCYPRESS_configurations=nameenvironment variables. - Variable management: Store sensitive values in
cypress.env.jsonor use theexposeconfig key withallowCypressEnv: falsefor modern variable handling. - Test type separation: Define separate blocks for
e2eandcomponenttesting within the same file to target different servers. - Source references: Configuration behavior is implemented in
system-tests/projects/config-with-ts/cypress.config.tsand documented inpackages/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 and the configurations key?
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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →