> ## Documentation Index
> Fetch the complete documentation index at: https://docs.e2e.army/llms.txt
> Use this file to discover all available pages before exploring further.

# Environment variables

> Every variable the runner and the first-party engines read, and what each one does.

The runner reads a closed set of variables. This page lists all of them, from
an inventory of every `process.env` and `env[...]` read in `@e2edev/e2e`,
`@e2edev/playwright`, `@e2edev/agent-device`, and `@e2edev/github`. A
variable not listed here has no effect on a run.

Almost every read goes through an `env` object the runner is handed once, at
config load. The exceptions are called out below.

Two readings recur. A **value** counts when it is set and not blank. A **flag**
is on when it is set and not blank, `0`, or `false`; the value is trimmed and
lowercased first, so `FALSE` is off and `no` and `off` are on.

## Model

| Variable                                                                       | Reading | Effect |
| ------------------------------------------------------------------------------ | ------- | ------ |
| The runner reads no model variable. The model is an AI SDK instance your       |         |        |
| config constructs, and the provider package behind it reads its own            |         |        |
| credential: `gateway()` from `ai` reads `AI_GATEWAY_API_KEY`, `openrouter()`   |         |        |
| from `@openrouter/ai-sdk-provider` reads `OPENROUTER_API_KEY`, `openai()`      |         |        |
| from `@ai-sdk/openai` reads `OPENAI_API_KEY`, and so on. Those reads happen    |         |        |
| in your config module and the provider, on the first model call, not in the    |         |        |
| runner; a missing model is `MODEL_UNAVAILABLE` when `agent` is first acquired, |         |        |
| and a missing key is the provider's own error on the first agent step. See     |         |        |
| [Choosing a model](/models).                                                   |         |        |

The order is spelled out under [Resolution order](/reference/config#resolution-order).

## Credentials

| Variable                   | Reading | Effect                                 |
| -------------------------- | ------- | -------------------------------------- |
| `E2E_USER_<NAME>_USERNAME` | set     | Replaces `credentials.<name>.username` |
| `E2E_USER_<NAME>_PASSWORD` | set     | Replaces `credentials.<name>.password` |

`<NAME>` is the credential name uppercased with every character outside
`A-Z0-9` replaced by `_`. A pair for a name absent from `credentials` is
ignored. These two are read as set-or-unset, so an empty string is a value.

## Run mode

| Variable | Reading | Effect                                                                                                                                                                 |
| -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CI`     | flag    | CI mode: `retries` defaults to 1 and `workers` to 1, `cache` defaults to `read-only`, a focused test is `ONLY_IN_CI`, and `reuseExisting` on an app command is ignored |

## Diagnostics

| Variable       | Reading | Effect                                                                                                                                    |
| -------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `NO_COLOR`     | set     | Plain CLI output. Colors are otherwise on for a TTY or in CI and off when piped                                                           |
| `FORCE_COLOR`  | set     | Colored CLI output even when piped                                                                                                        |
| `NODE_OPTIONS` | value   | Inspected for a TypeScript `--import` loader, which decides how the runner registers its own module hooks for `.ts` config and test files |

`--debug` and `--ai-trace` are flags, not variables; see
[CLI](/reference/cli#e2e-run).

## Telemetry

| Variable                 | Reading | Effect                                                                                                     |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------- |
| `E2E_TELEMETRY_DISABLED` | flag    | Turns anonymous usage telemetry off. `e2e telemetry disable` saves the same choice in the preferences file |
| `DO_NOT_TRACK`           | flag    | Same as `E2E_TELEMETRY_DISABLED`                                                                           |
| `E2E_TELEMETRY_DEBUG`    | flag    | Prints every telemetry event to stderr instead of sending it                                               |
| `XDG_CONFIG_HOME`        | value   | Directory of the preferences file, `$XDG_CONFIG_HOME/e2e`; default `~/.config/e2e`                         |
| `APPDATA`                | value   | The same on Windows, `%APPDATA%\e2e`; default `~/AppData/Roaming/e2e`                                      |

Telemetry also inspects, without reading a value, the presence of the markers
CI vendors and coding agents set, to attribute a run to a vendor or an agent
rather than a person. Only the derived name is sent.

| Markers                                                                                                                                                                                                                                                                    | Reported as                                                                                                                                                                                                                                            |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `GITHUB_ACTIONS`, `GITLAB_CI`, `CIRCLECI`, `BUILDKITE`, `JENKINS_URL`, `TRAVIS`, `BITBUCKET_BUILD_NUMBER`, `TF_BUILD`, `TEAMCITY_VERSION`, `CODEBUILD_BUILD_ID`, `VERCEL`, `NETLIFY`, `DRONE`, `SEMAPHORE`, `APPVEYOR`, `WOODPECKER`                                       | `ci_name`: `github-actions`, `gitlab`, `circleci`, `buildkite`, `jenkins`, `travis`, `bitbucket`, `azure-pipelines`, `teamcity`, `aws-codebuild`, `vercel`, `netlify`, `drone`, `semaphore`, `appveyor`, `woodpecker`; `unknown` when only `CI` is set |
| `CLAUDECODE`, `CLAUDE_CODE`, `CURSOR_AGENT`, `CURSOR_TRACE_ID`, `CODEX_SANDBOX`, `CODEX_THREAD_ID`, `CODEX_CI`, `GEMINI_CLI`, `COPILOT_GITHUB_TOKEN`, `COPILOT_MODEL`, `COPILOT_ALLOW_ALL`, `OPENCODE_CLIENT`, `AUGMENT_AGENT`, `ANTIGRAVITY_AGENT`, `REPL_ID`, `AI_AGENT` | `coding_agent`: `claude-code`, `cursor`, `codex`, `gemini-cli`, `copilot`, `opencode`, `augment`, `antigravity`, `replit`, `other`                                                                                                                     |
| `WSL_DISTRO_NAME`                                                                                                                                                                                                                                                          | `wsl: true`                                                                                                                                                                                                                                            |
| `npm_config_user_agent`                                                                                                                                                                                                                                                    | `package_manager`: the invoking package manager. `e2e init` reads the same variable to pick the install command                                                                                                                                        |

What is sent and how to read it is on the [Telemetry](/telemetry) page.

## Reporters

`@e2edev/github` reads the variables GitHub Actions sets, when a run finishes:

| Variable                                                                                   | Reading | Effect                                                                                                                                                                                                                                                                         |
| ------------------------------------------------------------------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `GITHUB_ACTIONS`                                                                           | value   | Without it the reporter posts nothing and says so                                                                                                                                                                                                                              |
| `GITHUB_REPOSITORY`, `GITHUB_RUN_ID`, `GITHUB_EVENT_NAME`, `GITHUB_WORKFLOW`, `GITHUB_JOB` | value   | Always set by the runner; a job missing one fails the reporter with the variable named. The repository and run id build the artifacts link, the event name is in the "not a pull request" row, and the workflow and job join the marker that lets a rerun find its own comment |
| `GITHUB_TOKEN`, `GH_TOKEN`                                                                 | value   | The token the comment is posted with; the first one set wins. Unset, the job summary is still written                                                                                                                                                                          |
| `GITHUB_EVENT_PATH`, `GITHUB_REF`                                                          | value   | The pull request number and head commit from the event payload, or the number from `refs/pull/N/merge`                                                                                                                                                                         |
| `GITHUB_SHA`                                                                               | value   | The commit source links point at when the event is not about a pull request                                                                                                                                                                                                    |
| `GITHUB_SERVER_URL`, `GITHUB_API_URL`                                                      | value   | The GitHub host, for Enterprise Server; `https://github.com` and `https://api.github.com` by default                                                                                                                                                                           |
| `GITHUB_STEP_SUMMARY`                                                                      | value   | The job summary file the comment text is appended to                                                                                                                                                                                                                           |

## Engines

| Variable                                  | Reading | Effect                                                                                                                                                                                                                                                 |
| ----------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `PLAYWRIGHT_BROWSERS_PATH`                | value   | Playwright's browser cache. The engine's `prepare` hook checks for the browser in-process only when the run's environment agrees with the process's own; otherwise it defers to the `playwright install` CLI, which is a no-op when nothing is missing |
| `E2E_AGENT_DEVICE_POOL_<TARGET>_<digest>` | value   | Written by `@e2edev/agent-device` in `prepare` and read back by each worker: the booted devices discovered for the target, so each worker slot resumes the device booted for it. Not meant to be set by hand                                           |

## What app processes inherit

An app `command` or `service` does not inherit the runner's environment. The
child receives `PATH`, `HOME`, `TMPDIR`, `TMP`, `TEMP`, `SystemRoot`, and
`COMSPEC` from `process.env`, plus whatever `command.env` sets. `APP_URL`,
which the scaffolded config reads for `playwright({ url })`, is read by your
config module, not by the runner; pass it to a dev server through
`command.env` if the server needs it too.

<CardGroup cols={2}>
  <Card title="Config" href="/reference/config" />

  <Card title="CLI" href="/reference/cli" />

  <Card title="Telemetry" href="/telemetry" />
</CardGroup>
