These variables configure the runner and first-party packages. In the tables, set means the variable exists, value means it is not blank, and flag means it is not blank, 0, or false. Flag values are case-insensitive.

export E2E_USER_ADMIN_PASSWORD="$ADMIN_PASSWORD"
export E2E_CACHE_DIR=~/.cache/e2e
export E2E_TELEMETRY_DISABLED=1

Reference

Model

Configure a model in e2e.config.ts. Its provider reads the API key: gateway() uses AI_GATEWAY_API_KEY, openrouter() uses OPENROUTER_API_KEY, and openai() uses OPENAI_API_KEY. Without AI_GATEWAY_API_KEY, gateway() uses a Vercel OIDC token. A missing credential fails on the first model call. Subscription models use a stored login instead. See Models and Subscriptions.

VariableExampleReadingEffect
E2E_OAUTH_CREDENTIALSE2E_OAUTH_CREDENTIALS="$(cat oauth.json)"valueThe stored subscription logins as JSON
OPENCODE_API_KEYOPENCODE_API_KEY=<key>valueReplaces the stored opencode-console login
XDG_CONFIG_HOMEXDG_CONFIG_HOME=~/.configvalueDirectory of the stored logins, $XDG_CONFIG_HOME/e2e/oauth.json; default ~/.config/e2e/oauth.json

E2E_OAUTH_CREDENTIALS

The stored subscription logins as JSON, the contents of oauth.json, for a machine nobody can sign in on.

  • The e2e/oauth/* models and e2e models read it in place of $XDG_CONFIG_HOME/e2e/oauth.json.
  • e2e login and e2e logout refuse to change it.
  • Refreshed tokens are not written back.

OPENCODE_API_KEY

An OpenCode Console service account API key or an OpenCode Go subscription API key. opencodeConsole() and e2e models opencode-console use it in place of the stored opencode-console login. OpenCode reads the same variable.

Credentials and secrets

VariableExampleReadingEffect
E2E_USER_<NAME>_USERNAMEE2E_USER_ADMIN_USERNAME=admin@example.testsetReplaces credentials.<name>.username
E2E_USER_<NAME>_PASSWORDE2E_USER_ADMIN_PASSWORD="$ADMIN_PASSWORD"setReplaces credentials.<name>.password
E2E_SECRET_<NAME>E2E_SECRET_API_KEY="$API_KEY"setReplaces the value of secrets.<name>
  • <NAME> is the name uppercased with every character outside A-Z0-9 replaced by _, so power-user becomes E2E_USER_POWER_USER_USERNAME.
  • Two credentials, or two secrets, whose names map to one <NAME> are INVALID_CONFIG at config load, set or not. So one rotation never replaces two entries. The message names the entries and the variables. For example, api-key and api_key both read E2E_SECRET_API_KEY; svc-a and svc_a both read E2E_USER_SVC_A_USERNAME and _PASSWORD.
  • A credential and a secret may share a name, since their prefixes differ.
  • A variable for a name absent from the config is ignored.
  • An empty password or secret is INVALID_CONFIG, and so is one shorter than 6 characters (code points). Redaction rewrites every occurrence of a value, and one that short would take ordinary text with it. An empty username is accepted.

Run mode

VariableExampleReadingEffect
CICI=1flagCI mode

CI

Turns on CI mode:

  • retries defaults to 1 and workers to 1.
  • cache defaults to read-only.
  • A focused test is ONLY_IN_CI.
  • reuseExisting on an app command is ignored.

Replay cache

VariableExampleReadingEffect
E2E_CACHE_DIRE2E_CACHE_DIR=~/.cache/e2evalueReplaces cache.dir

E2E_CACHE_DIR

Replaces cache.dir for e2e run and e2e cache, resolved from the project root.

  • ~ or a leading ~/ is the home directory.
  • --cache-dir wins over it.
  • A custom cache.store ignores it.
  • The cache mode stays as configured, and --no-cache still turns the cache off.

Diagnostics

VariableExampleReadingEffect
NO_COLORNO_COLOR=1setPlain CLI output. Without it, colors are on for a TTY or in CI, off when piped
FORCE_COLORFORCE_COLOR=1setColored CLI output even when piped
TERMTERM=dumbvaluedumb draws the e2e init wordmark at rest, without animation, as in CI
GITHUB_SHA, GITHUB_HEAD_REF, GITHUB_REF_NAMEGITHUB_REF_NAME=mainvalueThe commit and branch the report records under run.vcs when git cannot read the project root. GITHUB_HEAD_REF wins over GITHUB_REF_NAME

--debug and --ai-trace are flags, not variables; see CLI.

Telemetry

VariableExampleReadingEffect
E2E_TELEMETRY_DISABLEDE2E_TELEMETRY_DISABLED=1flagTurns anonymous usage telemetry and the update check off. e2e telemetry disable saves the same choice for telemetry in the preferences file
DO_NOT_TRACKDO_NOT_TRACK=1flagSame as E2E_TELEMETRY_DISABLED
E2E_UPDATE_CHECK_DISABLEDE2E_UPDATE_CHECK_DISABLED=1flagTurns the daily check for a newer e2e release off
NO_UPDATE_NOTIFIERNO_UPDATE_NOTIFIER=1flagSame as E2E_UPDATE_CHECK_DISABLED
npm_config_registrynpm_config_registry=https://npm.example.com/valueThe registry e2e upgrade reads versions from; default https://registry.npmjs.org/. Package managers set it for the commands they run
E2E_TELEMETRY_DEBUGE2E_TELEMETRY_DEBUG=1flagPrints every telemetry event to stderr instead of sending it
E2E_TELEMETRY_FLEETE2E_TELEMETRY_FLEET=acmevalueNames the platform running e2e for its users
XDG_CONFIG_HOMEXDG_CONFIG_HOME=~/.configvalueDirectory of the preferences file and the update check’s update-check.json, $XDG_CONFIG_HOME/e2e; default ~/.config/e2e
APPDATAAPPDATA=C:\Users\ada\AppData\RoamingvalueThe same on Windows, %APPDATA%\e2e; default ~/AppData/Roaming/e2e

E2E_TELEMETRY_FLEET

Names the platform running e2e for its users.

  • Events are attributed to fleet:<name> instead of a per-machine id.
  • No preferences file is written, and no notice is printed.
  • A value that is not a plain token is sent as other.

Detected environments

Telemetry also checks for the markers CI vendors and coding agents set. Only the derived name is sent.

MarkersReported 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, EAS_BUILD, BITRISE_IO, CM_BUILD_ID, CI_XCODE_CLOUDci_name: github-actions, gitlab, circleci, buildkite, jenkins, travis, bitbucket, azure-pipelines, teamcity, aws-codebuild, vercel, netlify, drone, semaphore, appveyor, woodpecker, eas, bitrise, codemagic, xcode-cloud; 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_AGENTcoding_agent: claude-code, cursor, codex, gemini-cli, copilot, opencode, augment, antigravity, replit, other
WSL_DISTRO_NAMEwsl: true
npm_config_user_agentpackage_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 page.

Reporters

@e2e-dev/github reads the variables GitHub Actions sets, when a run finishes:

VariableExampleReadingEffect
GITHUB_ACTIONSGITHUB_ACTIONS=truevalueWithout it the reporter posts nothing and says so
GITHUB_REPOSITORY, GITHUB_RUN_ID, GITHUB_EVENT_NAME, GITHUB_WORKFLOW, GITHUB_JOBGITHUB_REPOSITORY=acme/shopvalueAlways set by the runner. A missing one fails the reporter, naming the variable. The repository and run id build the artifacts link. The event name shows in the “not a pull request” row. The workflow and job join the marker a rerun finds its own comment by
GITHUB_TOKEN, GH_TOKENGITHUB_TOKEN=<token>valuePosts the comment; the first one set wins. Unset, the job summary is still written. A fork’s pull_request token is read-only and cannot post; see When nothing is posted
GITHUB_EVENT_PATH, GITHUB_REFGITHUB_REF=refs/pull/42/mergevalueThe pull request number and head commit from the event payload, or the number from refs/pull/N/merge
GITHUB_SHAGITHUB_SHA=<commit>valueThe commit source links point at when the event is not about a pull request
GITHUB_WORKSPACEGITHUB_WORKSPACE=/home/runner/work/shop/shopvalueThe checkout root. Source links add the project’s path inside it, so a suite in a subdirectory links to the right file
GITHUB_SERVER_URL, GITHUB_API_URLGITHUB_SERVER_URL=https://github.example.comvalueThe GitHub host, for Enterprise Server. Default https://github.com and https://api.github.com
GITHUB_STEP_SUMMARYGITHUB_STEP_SUMMARY=<file>valueThe job summary file the comment text is appended to

Engines

VariableExampleReadingEffect
PLAYWRIGHT_BROWSERS_PATHPLAYWRIGHT_BROWSERS_PATH=~/.cache/ms-playwrightvaluePlaywright’s browser cache, honored by the engine’s prepare hook
PLAYWRIGHT_SKIP_BROWSER_GCPLAYWRIGHT_SKIP_BROWSER_GC=0valueDefaults to 1 for the engine’s browser install, which keeps other browsers in the cache. 0 lets the install remove them
KERNEL_API_KEYKERNEL_API_KEY=<key>valueThe API key kernel() from @e2e-dev/kernel creates browsers with. Unset, the browser lease fails. See Kernel
LIGHTPANDA_PATHLIGHTPANDA_PATH=/opt/lightpandavalueThe binary lightpanda() from @e2e-dev/lightpanda starts a CDP server with. Unset, lightpanda on PATH, ~/.lightpanda, or ~/.local/bin. See Lightpanda
EXPO_TOKENEXPO_TOKEN=<token>valueThe Expo access token easSimulators() from @e2e-dev/eas uses
HOME, USERPROFILEHOME=/home/adavalueWhere easSimulators() finds the eas-cli login without EXPO_TOKEN: USERPROFILE on Windows, HOME elsewhere, the OS user’s home when unset
LIMRUN_API_KEYLIMRUN_API_KEY=<key>valueThe API key limrun() from @e2e-dev/limrun leases devices with. Unset, the lease fails with INVALID_CONFIG. See Limrun
LIMRUN_BASE_URLLIMRUN_BASE_URL=<url>valueThe Limrun API host. Default https://api.limrun.com
LT_USERNAME, LT_ACCESS_KEYLT_USERNAME=acmevalueThe TestMu AI username and access key testmu() from @e2e-dev/testmu leases devices with. With either unset, the device lease fails. testmuBrowsers() from @e2e-dev/testmu/web puts them only in the CDP URL of each browser session, and with either unset the browser lease fails. See TestMu AI
TESTMU_API_ENDPOINTTESTMU_API_ENDPOINT=<url>valueThe TestMu AI sessions API base URL testmu() looks up session recordings at. Default https://mobile-api.lambdatest.com/mobile-automation/api/v1. A value that is not an http(s) URL, or carries a username or password, fails the lookup with INVALID_CONFIG. agent-device’s TestMu AI plugin reads it too
E2E_WEB_BROWSERS_<TARGET>_<digest>-value@e2e-dev/web writes it in prepare; each worker reads it to find its leased browser. Don’t set it by hand
E2E_AGENT_DEVICE_POOL_<TARGET>_<digest>-value@e2e-dev/mobile writes it in prepare; each worker reads it to find its booted device. Don’t set it by hand

EXPO_TOKEN

The Expo access token easSimulators() from @e2e-dev/eas starts and stops simulator sessions with. See EAS Simulators.

  • Unset, it uses the eas-cli login in .expo/state.json under the home directory (HOME, USERPROFILE).
  • With neither, the device lease fails.

What app processes inherit

An app command receives PATH, HOME, TMPDIR, TMP, TEMP, SystemRoot, and COMSPEC, plus the variables command.inheritEnv matches and whatever command.env sets.

The scaffolded config module reads APP_URL, not the runner. If the dev server needs it too, pass it through command.env.