---
modificationDate: November 12, 2026
title: Expo Simulators CLI reference
description: Reference for the experimental eas simulator commands that create, inspect, monitor, control, list, route network traffic for, and stop remote simulator sessions.
---

This documentation is available as Markdown for AI agents and LLMs. See the [full Markdown index](https://docs.expo.dev/llms.txt) or append .md to any documentation URL.

# Expo Simulators CLI reference

Reference for the experimental eas simulator commands that create, inspect, monitor, control, list, route network traffic for, and stop remote simulator sessions.

<AgentInstructions>

## Submitting Feedback

If you encounter errors, misleading or outdated information, report it so Expo can be improved:

Preferred command:
npx --yes submit-expo-feedback@latest --category docs --subject "/eas/simulators/reference/cli/" "<actionable feedback>"

Direct HTTP fallback:
curl -X POST https://api.expo.dev/v2/feedback/docs-send -H 'Content-Type: application/json' -d '{"url":"/eas/simulators/reference/cli/","feedback":"🤖 Agent feedback for docs: <specific, actionable description> (<model>, <harness>)"}'

Only submit when you have something specific and actionable to report. Try to give the most context.

## Navigation

When answering a related or follow-up question, fetch the relevant page below as Markdown (.md) instead of guessing; use llms.txt for the full map.

You are here: Expo Services > Expo Simulators > Reference
Pages in this section:
- [Session types](https://docs.expo.dev/eas/simulators/reference/session-types.md)
- [CLI](https://docs.expo.dev/eas/simulators/reference/cli.md) (this page)
- [REST API](https://docs.expo.dev/eas/simulators/reference/rest-api.md)
- [Devices](https://docs.expo.dev/eas/simulators/reference/devices.md)
- [Usage and billing](https://docs.expo.dev/eas/simulators/reference/usage-and-billing.md)
- [Security and data](https://docs.expo.dev/eas/simulators/reference/security-and-data.md)
Full documentation tree: [llms.txt](https://docs.expo.dev/llms.txt)

</AgentInstructions>

The `simulator:*` commands are experimental. Install or update [EAS CLI](https://docs.expo.dev/eas/cli.md) before running them:

```sh
eas simulator:start --help
```

The `--help` flag displays the available options for `simulator:start`.

The start command is also available as `eas simulator`, `eas sim:start`, and the hidden alias `eas sim`. The other commands have matching `eas sim:*` aliases, such as `eas sim:list` and `eas sim:stop`.

To manage sessions without EAS CLI, use the [Expo Simulators REST API](https://docs.expo.dev/eas/simulators/reference/rest-api.md).

## Commands

| Command | Purpose |
| --- | --- |
| [`simulator:availability`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatoravailability) | Check whether the current project's account can use Expo Simulators |
| [`simulator:start`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatorstart) | Create a session and wait for its controller configuration |
| [`simulator`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatorstart) | Same command as `simulator:start` |
| [`simulator:control`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatorcontrol) | Run a supported device action on a running iOS session |
| [`simulator:exec`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatorexec) | Run another command with **.env.eas-simulator** loaded |
| [`simulator:events`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatorevents) | Show recorded activity or follow activity from a running session |
| [`simulator:logs`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatorlogs) | Show app logs from an iOS session, or download them after it stops |
| [`simulator:egress`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatoregress) | Run the local egress client for a session started with `--egress local` |
| [`simulator:get`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatorget) | Get status, connection details, dashboard URL, timestamps, and artifacts |
| [`simulator:list`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatorlist) | List and filter sessions for the current project |
| [`simulator:stop`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatorstop) | Stop a session |

## `simulator:availability`

```sh
eas simulator:availability --json
```

The `--json` flag is optional. It prints a stable, machine-readable result for agents and automation; omit it for human-readable output. The JSON object contains `available` and `accountName`. When the account does not have access, it also contains `billingUrl`, the URL of the account's billing page. This command does not create a session or consume simulator usage.

## `simulator:start`

The session type determines which interface Expo Simulators provisions with the remote device. Every type includes a browser preview. Choose agent-device, Argent, or Appium to add programmatic control, or choose `web-preview-only` for the browser preview and direct iOS controls:

#### agent-device

Use [agent-device](https://docs.expo.dev/agents/agent-device.md) for accessibility-driven device actions and app installation.

```sh
eas simulator:start --platform ios --type agent-device --name "Checkout flow screenshots" --non-interactive
```

#### Argent

Use [Argent](https://docs.expo.dev/agents/argent.md) to run its remote device tools through the session.

```sh
eas simulator:start --platform ios --type argent --name "Checkout flow screenshots" --non-interactive
```

#### Appium

Use Appium when you want to connect an existing Appium client or test suite.

```sh
eas simulator:start --platform ios --type appium --name "Checkout flow tests" --non-interactive
```

#### Browser preview only

Use the browser preview without provisioning a programmatic controller.

```sh
eas simulator:start --platform ios --type web-preview-only --name "Design review" --non-interactive
```

Important flags:

| Flag | Description |
| --- | --- |
| `-p, --platform` | `android` or `ios`. Required in non-interactive mode; prompted for in an interactive terminal |
| `--name` | Human-readable session name shown by `simulator:list`, `simulator:get`, and expo.dev |
| `--tag` | Label that groups sessions, such as one tag for each app variant. Repeat the flag for multiple tags. Stored in lowercase |
| `--device` | Android virtual device hardware profile, or iOS Simulator name or unique device identifier (UDID). The runner chooses a device when omitted |
| `--system-image` | Android SDK system image package, such as `system-images;android-35-ext15;google_apis_playstore;x86_64`. Android only. Quote the value because it contains semicolons. Omit it to use the runner default. See [Devices](https://docs.expo.dev/eas/simulators/reference/devices.md). |
| `--build-id` | Expo Build to install and launch before the session is ready |
| `--build-fingerprint` | Fingerprint hash of an Expo Build. Installs the most recent finished build with this fingerprint that the simulator can install |
| `--application-archive-url` | Application archive to download, install, and launch before the session is ready |
| `--expo-go` | Install and launch the Expo Go version that matches the current project's Expo SDK |
| `--sdk-version` | Expo SDK used to select Expo Go. Only valid with `--expo-go`; defaults to the current project SDK |
| `--launch-arg` | Argument passed to the installed app when it launches. Repeat the flag for multiple arguments |
| `--open-url` | Expo or development-client URL to open in the installed app after launch |
| `--type` | Session type. Defaults to `agent-device`. Every type includes a browser preview. Use `agent-device`, `appium`, or `argent` to add programmatic control, or `web-preview-only` for the browser preview only |
| `--public-link` | Print a public browser preview link that contains the preview token, and make **Share** in the preview copy it. Anyone with the link can view the simulator, and on iOS, control it. Without this flag, preview links require an Expo login with access to the project. See [Browser preview links](https://docs.expo.dev/eas/simulators/reference/cli.md#browser-preview-links) |
| `--frame-ancestor` | Origin of a web page that can embed the browser preview in an iframe, such as `https://app.example.com` or `https://*.example.com`. Repeat for up to 10 origins. Also prints the preview host URL with the preview token. See [Show an Expo Simulators session on your own web page](https://docs.expo.dev/eas/simulators/how-to/embed-a-session.md) |
| `--cors-origin` | Origin of a web page that can call the preview host's API, for example to render the device screen with `@expo/hub-client`. Same rules as `--frame-ancestor`. Also prints the preview host URL with the preview token |
| `--package-version` | Controller package version. Defaults to the service's latest version |
| `--max-duration-minutes` | Automatic session stop time, up to the plan limit: 40 minutes on the Free plan and 115 minutes on paid plans. Defaults to the plan limit |
| `--egress` | `local` routes the device's network traffic through this machine. On Android, all TCP traffic from the emulator. On iOS, HTTP(S) and WebSocket traffic that honors the system proxy or proxy environment variables, such as gRPC and libcurl. See [Network traffic and local egress in Expo Simulators](https://docs.expo.dev/eas/simulators/how-it-works/network-inspection.md) |
| `--egress-allow` | Exact `host:port` on this machine or its network that the simulator can reach through local egress, such as `localhost:3000`. Repeat for multiple destinations. Requires `--egress local` |
| `--network-capture` | Record HTTP(S) traffic from apps on an iOS device as an HTTP Archive (HAR). iOS only. Not compatible with `--egress local`. See [Record network traffic](https://docs.expo.dev/eas/simulators/how-it-works/network-inspection.md#record-network-traffic) |
| `--network-capture-field` | What a recording also keeps: `header`, `query`, `request-body`, or `response-body`. Repeat the flag or pass a comma-separated list. Requires `--network-capture` |
| `--max-idle-time-minutes` | Stop after this many minutes without session activity. When omitted, the session has no idle timeout and runs until its maximum duration. Not supported for Android `web-preview-only` |
| `--out-config-type` | `dotenv` (default) to write **.env.eas-simulator**, or `env` to print shell exports |
| `--[no-]force` | Whether to create a new session when a session ID already exists in the environment. Defaults to `true` |
| `--non-interactive` | Return after the session is ready instead of staying attached |
| `--json` | Print machine-readable output and imply non-interactive mode |

`--build-id`, `--build-fingerprint`, `--application-archive-url`, and `--expo-go` are mutually exclusive application sources. `--launch-arg` and `--open-url` require one of those sources because the start command needs an installed application to launch.

The default `dotenv` output writes configuration even when you pass `--json`. Use `--out-config-type env` when you explicitly do not want the file. The `env` output does not export `EAS_SIMULATOR_SESSION_ID`, so pass `--id <session-id>` to `simulator:get`, `simulator:stop`, `simulator:events`, `simulator:logs`, and `simulator:control`.

Common JSON output fields have this shape. The fields inside `remoteConfig` depend on the selected controller:

```json
{
  "id": "<session-id>",
  "name": "Checkout flow screenshots",
  "type": "<controller-type>",
  "deviceRunSessionUrl": "https://expo.dev/accounts/<account>/projects/<project>/simulator-sessions/<session-id>",
  "remoteConfig": {
    "<controller-specific-key>": "<value>"
  }
}
```

Treat `remoteConfig` as secret because it includes controller credentials. The browser preview link is `remoteConfig.webPreviewUrl`, or `remoteConfig.previewUrl` for a `web-preview-only` session.

### Browser preview links

EAS CLI prints private browser preview links by default. A private link opens only for a person who signs in to an Expo account that can view the project:

```text
https://expo.dev/accounts/<account>/projects/<project>/simulator-sessions/<session-id>/preview
```

With `--public-link`, EAS CLI prints a public link that contains the preview token, with a warning. Anyone who has a public link can view the simulator without an Expo login, and on iOS, control it.

| `--json` field | Private links (default) | Public links (`--public-link`) |
| --- | --- | --- |
| `remoteConfig.webPreviewUrl` or `remoteConfig.previewUrl` | The private link | The public link, with the preview token |
| `remoteConfig.previewApiUrl` | Not included | The preview host URL, with the preview token |

With `--frame-ancestor` or `--cors-origin`, `remoteConfig.previewApiUrl` contains the preview host URL with the preview token, even for a session with private links. The terminal output also shows this URL, with a warning. A web page on an allowed origin uses this URL to show the session. See [Show an Expo Simulators session on your own web page](https://docs.expo.dev/eas/simulators/how-to/embed-a-session.md).

Expo Simulators saves the `--public-link` setting with the session, and `simulator:get` prints the kind of link that the saved setting selects. `simulator:get` does not include `previewApiUrl` for a session with private links, even when the session started with `--frame-ancestor` or `--cors-origin`. See [Expo Simulators security model](https://docs.expo.dev/eas/simulators/how-it-works/security-model.md#the-browser-preview).

### Interactive and non-interactive behavior

Without `--non-interactive` or `--json`, the start command stays attached in an interactive terminal and polls the session. Press Ctrl + C once to stop it. EAS CLI resets **.env.eas-simulator** after it confirms the session ended. When `CI` is set or standard input is not a terminal, such as in an agent shell, the command runs non-interactively even without the flag.

With `--non-interactive` or `--json`, the command returns after the controller is ready. You must stop the session separately.

## `simulator:control`

Discover direct actions on a running iOS session, then run an action from its catalog:

```sh
eas simulator:control --id <session-id> --json
eas simulator:control appearance.set dark --id <session-id>
eas simulator:control screenshot.capture --output ./screen.png --id <session-id>
```

The command uses the session's preview server and works with private links. It supports iOS sessions, including `web-preview-only`. Android sessions use a controller. Omit the action to list available actions. Their names and arguments depend on the serve-sim version running in the session.

`--id` selects the session. Without it, the command reads the ID from **.env.eas-simulator** or the shell environment. `--output` saves a returned file on your computer. `--json` returns the catalog or the action result as JSON and implies non-interactive mode.

For session selection and action discovery, see [Control a remote iOS Simulator with EAS CLI](https://docs.expo.dev/eas/simulators/how-to/control-with-eas-cli.md).

## `simulator:exec`

`simulator:exec` is controller-agnostic. It loads the connection variables for the active session from **.env.eas-simulator**, then spawns the command and arguments that follow.

Use the command pattern for the controller selected when the session started:

#### agent-device

```sh
eas simulator:exec npx agent-device@latest <command> [args...]
```

#### Argent

```sh
eas simulator:exec argent run <tool> [args...]
```

#### Appium

```sh
eas simulator:exec <appium-client> [args...]
```

`simulator:exec` does not implement device actions. It only supplies the active session's connection environment and runs the command that follows. The available actions and argument syntax come from [agent-device](https://docs.expo.dev/agents/agent-device.md), [Argent](https://docs.expo.dev/agents/argent.md), or your Appium client. For Appium, `simulator:exec` sets `APPIUM_URL` and `APPIUM_CAPS` for your client.

## `simulator:events`

Show a snapshot of the activity recorded for the session referenced by **.env.eas-simulator**:

```sh
eas simulator:events
```

Pass a session ID to inspect another session:

```sh
eas simulator:events --id <session-id>
```

The default text output condenses related operations into a readable timeline. It includes the timestamp, controller, summary, and duration when available. This command shows session and controller activity from agent-device, Argent, or Appium, not application runtime logs. For app logs, use [`simulator:logs`](https://docs.expo.dev/eas/simulators/reference/cli.md#simulatorlogs).

Follow new activity while a session is running:

```sh
eas simulator:events --follow
```

The `-f` short flag is equivalent to `--follow`. The command stops following when the session ends. Press Ctrl + C to stop following earlier.

For agents and automation, request the raw event records as JSON:

```sh
eas simulator:events --json
```

The JSON object contains `deviceRunSessionId` and an `events` array. Common event fields include `eventId`, `ts`, `producer`, `type`, and `summary`, with operation ID, outcome, duration, and controller-specific data when available. `--json` cannot be combined with `--follow`.

## `simulator:logs`

Show the latest app logs from the running iOS session referenced by **.env.eas-simulator**:

```sh
eas simulator:logs
```

The command prints the latest buffered lines, 100 by default. Use `--limit` to change the number. By default, it shows only logs from installed apps. To include system logs, use `--scope all` with `--follow`. Add `--timestamp` to show the time of each line. After the first 30 minutes of the session, new lines appear only while you follow the logs with `--follow`.

To collect the logs of an action, start following before you run the action:

```sh
eas simulator:logs --follow
```

The `-f` short flag is equivalent to `--follow`. To save the logs, redirect the output to a file:

```sh
eas simulator:logs --follow > logs.txt
```

Press Ctrl + C to stop following.

Use `--json` to get the buffered lines as JSON. The `lines` array contains each line's sequence number in `seq`, its time in `at`, and the log record in `raw`. You cannot use `--json` together with `--follow`.

After the session stops, download its saved app logs:

```sh
eas simulator:logs --id <session-id> --output ./app-logs.ndjson
```

For each iOS device that writes app logs, Expo Simulators saves them as an **app-logs.ndjson** artifact. Each artifact holds only the app logs from the first 30 minutes of the session, up to 20 MiB. When a session has more than one device, the command asks you to select a file. In non-interactive mode, it stops with an error that lists the files. Pass `--artifact <index>` with a number from that list, starting at 1. Android sessions do not provide logs through this command.

## `simulator:egress`

Run the local egress client for the session in **.env.eas-simulator**:

```sh
eas simulator:egress
```

The session must have started with `--egress local`. In interactive mode, `simulator:start` runs the egress client in the same terminal, so you do not need this command. With `--non-interactive`, run `simulator:egress` in another terminal and keep it running for the life of the session.

Use `--config-type env` to read the session credentials from the shell environment instead of **.env.eas-simulator**. Press Ctrl + C to stop the egress client. The session keeps running, and proxied requests fail until the client connects again.

## `simulator:get`

Get the session referenced by **.env.eas-simulator**:

```sh
eas simulator:get --json --non-interactive
```

Get another session explicitly:

```sh
eas simulator:get --id <session-id> --json --non-interactive
```

The response includes:

-   ID, name, tags, type, status, and platform
-   Created, started, finished, and updated timestamps
-   The expo.dev simulator session URL
-   Controller connection configuration
-   Session artifacts, when present, with each artifact's `id`, `name`, `filename`, `fileSizeBytes`, `metadata`, and `downloadUrl`. `fileSizeBytes` appears only after the session stops

## `simulator:list`

```sh
eas simulator:list --platform ios --status in-progress --json --non-interactive
```

Filters can be repeated:

| Filter | Values |
| --- | --- |
| `--platform` | `android`, `ios` |
| `--type` | `agent-device`, `appium`, `argent`, `web-preview-only` |
| `--status` | `new`, `queued`, `starting`, `in-progress`, `stopped`, `errored` |
| `--name` | Text that the session name starts with. Case does not matter. Takes one value |
| `--tag` | Tag. A session must have every listed tag |

Use `--limit` to control page size (10 by default, 100 at most) and `--after` with the previous response's `endCursor` for pagination.

## `simulator:stop`

Stop the session referenced by **.env.eas-simulator**:

```sh
eas simulator:stop
```

Stop a specific session:

```sh
eas simulator:stop --id <session-id>
```

Running `simulator:stop` on a session that already stopped succeeds.

Use `--json` for a machine-readable object containing the session `id` and final `status`.

## .env.eas-simulator

While a session is active, the managed file contains its session ID:

```sh .env.eas-simulator
EAS_SIMULATOR_SESSION_ID='<session-id>'
```

After the session stops and EAS CLI resets the file, only the comment header remains.

Controller connection variables depend on the selected type:

| Controller | Connection variables |
| --- | --- |
| agent-device | `AGENT_DEVICE_DAEMON_BASE_URL`, `AGENT_DEVICE_DAEMON_AUTH_TOKEN` |
| Argent | `ARGENT_TOOLS_URL` and, when required, `ARGENT_AUTH_TOKEN` |
| Appium | `APPIUM_URL`, `APPIUM_CAPS` |

A session started with `--egress local` also adds `EAS_SIMULATOR_EGRESS_URL`, `EAS_SIMULATOR_EGRESS_TOKEN`, `EAS_SIMULATOR_EGRESS_FINGERPRINT`, `EAS_SIMULATOR_EGRESS_PORT`, `EAS_SIMULATOR_EGRESS_PLATFORM`, and `EAS_SIMULATOR_EGRESS_ALLOW`.

When the file contains a session ID, its values replace the same variables in your shell environment for `simulator:start`, `simulator:exec`, `simulator:get`, `simulator:stop`, `simulator:events`, `simulator:logs`, `simulator:control`, and `simulator:egress`. The only exception is `simulator:egress --config-type env`, which does not read the file. Some commands also read `EAS_SIMULATOR_SESSION_ID` from your shell environment: `simulator:get`, `simulator:stop`, `simulator:events`, `simulator:logs`, and `simulator:control`. They use it when the file has no session ID and you do not pass `--id`.

Add the file to **.gitignore**:

```sh .gitignore
.env.eas-simulator
```

Do not modify its values while the session is running.
