Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/gmackie-eas-simulator
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: backend, testing, devops, agent-building
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/eas-simulator
What's inside
- Skill name
eas-simulator- Description
- EAS service (paid). Run and control a user's app on a remote iOS/Android simulator hosted on EAS cloud. Read before running any `eas simulator:*` commands - it has the current syntax for this experimental API. Use whenever the user needs a simulator they can't run locally - 'run my app on a cloud simulator', 'use eas simulator to run/install/screenshot my app', 'I'm on Linux/Cursor and need an iOS device', 'no sim on this box / headless CI', 'let an agent click through my app and screenshot it', 'test my dev build on a remote sim with live reload', 'stream a sim to my browser' - even when they don't say 'EAS Simulator' or 'cloud'. On a host WITHOUT a local simulator (Linux, CI, cloud sandbox) it's the default; on macOS, do NOT auto-trigger for a plain 'run on the simulator' - use it only for a cloud/remote/shareable sim, an iOS version they lack, or an agent-driven session. NOT for local sims (expo run:ios, Xcode, Android Studio), EAS Build/Update, web preview, or physical devices.
- License
- MIT
- Metadata
- tags: deployment,eas,expo,mobile · groups: expo · source: https://github.com/expo/skills@50f59f837ddb7595d8c6683c693207e265d58c43:plugins/expo/skills/eas-simulator · invocation: model
- Instructions
- 203 lines in SKILL.md · view on GitHub
Files (6)
- SKILL.md
- openai.yaml · agents/
- controllers.md · references/
- run-your-app.md · references/
- troubleshooting.md · references/
- skill.json
SKILL.md (first lines)
# EAS Simulator
> **EAS service - costs apply.** EAS Simulator runs on Expo Application Services cloud infrastructure, a paid product with free-tier limits; remote simulator sessions use your plan's compute allowance. See https://expo.dev/pricing.
EAS Simulator runs a remote iOS simulator or Android emulator on EAS infrastructure that you drive from your machine, from the CLI, from an AI agent (via `agent-device`), and from a browser preview. It's the unlock for **environments that can't run a simulator locally** (Linux boxes, cloud/background agents like Cursor Cloud), and for letting an agent *verify* a change on a real device instead of only reasoning about code.
The `simulator:*` commands are **experimental and hidden**, and need a recent eas-cli (≥ 20.3.0 as of writing), which is why this skill runs everything via `npx --yes eas-cli@latest`. Flags and verbs may change; if a command fails, **`<cmd> --help` is authoritative.**
## When to use
The frontmatter `description` carries the trigger phrases. In short: use this to get a user's app onto a **cloud** simulator and interact with it, especially from a Mac-less or cloud/sandbox agent. **Not** for local sims (`expo run:ios`, Xcode, Android Studio), store builds/signing (that's EAS Build), or physical devices. For the macOS case, see *Cloud vs local* next.
## Cloud vs local: decide this first
- **Non-macOS** (Linux / CI / cloud sandbox like Cursor Cloud, detect via `uname -s` ≠ `Darwin`): the only way to get a sim, **proceed, once you've confirmed access** (see *Check availability first* below).
- **macOS:** local sims exist and a cloud session costs money + latency, so **ask first** ("a remote cloud sim, to share a live preview, offload, or test an iOS version you lack, or just run locally?") unless the user explicitly said cloud/remote/shareable.
- Always honor an explicit choice; for "run it locally" hand off to `expo run:ios` / Xcode.
```bash
# Programmatic detection — run this to decide before doing anything else:
if [ "$(uname -s)" != "Darwin" ] || ! xcrun --find simctl &>/dev/null 2>&1; then
echo "no local sim — proceed with EAS Simulator"
else
echo "local sim available — ask the user (cloud or local?)"
fi
```
## Prerequisites
- **Run every `eas` command via `npx --yes eas-cli@latest …`**, guarantees a CLI new enough to have `simulator:*` (a global `eas` is often too old), and `--yes` skips npx's prompt. (Bare `eas` is fine if `eas --version` is current.)
- **Authenticated.** Interactive machine → `npx --yes eas-cli@latest login`. **Cloud sandbox / CI / headless agent has no browser login, set `EXPO_TOKEN`** (expo.dev → Account → Access Tokens) in the env instead. Verify either way with `npx --yes eas-cli@latest whoami`.
- Run from an Expo **project directory.** A fresh app needs one-time setup: `npx --yes eas-cli@latest init` to create/link the project (when there's no `projectId`), and **set `ios.bundleIdentifier`** in app config if it's missing, a fresh `create-expo-app` often has none, and `prebuild`/`eas build` need it (they prompt or fail without it; e.g. `dev.<owner>.<slug>`). Read current config with `npx expo config --json` (it may live in `app.config.js`). The first Mode-C run is slow (native build); later runs reuse it.
- A controller to drive the device. This skill uses **agent-device** (open source, MIT), run on demand via `npx agent-device@latest`, nothing globally installed. **argent** is an alternative (`--type argent` in `simulator:start`); see [references/controllers.md](./references/controllers.md).
- **`.env.eas-simulator`** is written/managed by eas-cli (not this skill): it holds the session id (`EAS_SIMULATOR_SESSION_ID`) + the daemon URL/**token**, so `get`/`stop`/`exec` default to that session (usually **omit `--id`**; pass `--id <id>` to target another). It carries a **token → keep it gitignored** (eas-cli marks it "do not commit" but may not add the ignore rule, and a fresh app's `.gitignore` won't cover it, add `.env.eas-simulator` if missing).
- `--max-duration-minutes` is paid-plan only; otherwise a default applies.
- **The command blocks assume a POSIX shell** (bash/zsh), `printf`, `lsof`, `$(seq …)` loops won't run in cmd/PowerShell. On Windows, run them in WSL or Git Bash, or translate as you go (the `eas-cli`/`agent-device` invocations themselves are cross-platform).
## Check availability first
EAS Simulator is a **limited-access** EAS feature that is still rolling out, so it isn't enabled on every account. Confirm access **before** starting a session, this is a read-only check: no session, no billing.
```bash
npx --yes eas-cli@latest simulator:availability --json
# → {"available": true, ...} enabled → continue to the core loop
# → {"available": false, ...} not enabled → do NOT start a session
```
If it's **not** available, don't call `simulator:start` (it will fail). Instead, hand off gracefully so you keep making progress without this skill:
- Tell the user EAS Simulator isn't available on their account yet, it's coming soon.
- Fall back to their normal local path for the actual goal, `expo run:ios` / Xcode / Android Studio for a local sim/emulator, an EAS Build, or whatever else fits. Don't dead-end on the cloud sim; the request was almost never "use EAS Simulator specifically."
(If `simulator:availability` isn't recognized, the CLI is too old, upgrade, or treat a `not enabled for this account` error from `simulator:start` the same way: stop and fall back.)
## The core loop (always the same)
A session is: **start → (install your app) → drive → stop.** `eas-cli` owns the *session*; the device *verbs* (open/tap/screenshot) come from the controller, which `npx --yes eas-cli@latest simulator:exec` runs for you with the session's connection env loaded.
```bash
# 1. Start a session (boots the remote sim + agent-device daemon; writes .env.eas-simulator).
printf '# managed by eas-cli\n' > .env.eas-simulator # clear any stale session first
npx --yes eas-cli@latest simulator:start --platform ios --type agent-device --non-interactive \
--name "Checkout flow screenshots" # always name it — see 'Always name the session'
# Then confirm it's live: simulator:get --json → status IN_PROGRESS (bounded poll in run-your-app.md).
# 2. Drive it through `exec` (loads the session env, then runs the command you give it).
# agent-device runs on demand via npx — nothing installed globally.
npx --yes eas-cli@latest simulator:exec npx agent-device@latest open <app-or-url> --platform ios
npx --yes eas-cli@latest simulator:exec npx agent-device@latest snapshot -i # interactive UI tree → @e1, @e2 refs
npx --yes eas-cli@latest simulator:exec npx agent-device@latest press @e2 # tap a ref (NOTE: 'press', not 'tap')
npx --yes eas-cli@latest simulator:exec npx agent-device@latest screenshot ./shot.png
# 3. Stop (ends billing; tears down the VM) and reset the dotenv. Omit --id to target the dotenv session.
npx --yes eas-cli@latest simulator:stop
printf '# managed by eas-cli\n' > .env.eas-simulator
```
To **watch** it live, hand the user the `webPreviewUrl` that `start` prints (an `--type agent-device` iOS session runs serve-sim alongside the daemon, so it emits one, agent control *and* a browser preview in one session; Android has no preview, and `--type serve-sim` is preview-only). **This URL is for the *user's* browser, you cannot open it for them, and it must never touch the sim:**
- **"Open it here" (Cursor/VS Code)** → print the URL on its own line and tell the user to open Simple Browser (`Cmd/Ctrl+Shift+P` → "Simple Browser: Show") and paste it. Then **stop**: do not shell out to a system browser or a Cursor/VS Code URL handler, and do not ask "did a tab appear?", you can't confirm it, the handoff is done.
- **Never `open` the `webPreviewUrl` on the sim.** It's a browser preview, not a deep link and not an `agent-device open` argument; routing it to the device renders a browser-in-a-browser (a real past failure).
- **Headless agent** (no display) → just return the URL as the deliverable.
- **Keeping it alive for the user to drive** → bound it: start with `--max-duration-minutes N` so it auto-stops; tell them it bills until stopped and when it auto-stops; offer to reopen/extend when it ends. (This is the one case where "stop right away" doesn't apply; one-shot `screenshot`/`get` runs still stop immediately.)
`start` also prints a job-run URL.
## Always name the session
Pass `--name "<description>"` on every `simulator:start`. The name appears in `simulator:list`, `simulator:get`, and on the **Simulator sessions** page on expo.dev, where it replaces the generic title on each row. Unnamed, every row reads "Simulator session" over a random id, a wall of identical entries nobody can navigate. Write the name for a **human scanning that list days later**, not for yourself during this run.
Write what the session is *for*, in a few plain words:
```bash
--name "Checkout flow screenshots" # what you did
--name "Dev build — dark mode fix" # what you were testing
--name "Login repro for issue 412" # why it exists
```
Rules:
- Derive it from the user's request, not from the mode or the tooling. `Mode C session`, `agent-device ios`, and `test` say nothing.
- **Length: aim for 3–6 words, ~40 characters, and treat 50 as the practical limit.** It renders as a single-line title in a narrow table column, so a long name clips. The API accepts up to **255 characters** and rejects an empty/whitespace-only name, but 255 is a ceiling you never approach, not a target. One noun phrase, no sentences.
- Be specific within that budget. Include a ticket or PR number when there is one.
- **Sentence case:** capitalize the first word only, and leave identifiers in their real casing (`Dev build for expo-router v4`, `Repro for EXPO-1234`). It's a row title, so no Title Case, no all-lowercase, and no trailing period.
- **Don't repeat what the table already shows.** Every row already displays the session id, platform, start time, duration, and who created it, so no ids, no `iOS`, no dates, no your-own-name. Spend the whole budget on what those columns can't say: the purpose.
- If the user names it, use their name as-is.
- Sessions are per-run, so name each new one for that run. Don't reuse an old name for different work.
`--name` is newer than `simulator:start` itself, so an older installed `eas-cli` can reject it. If that happens, run via `npx --yes eas-cli@latest` or upgrade; as a last resort, retry once without `--name` (the session starts unnamed). See [references/troubleshooting.md](./references/troubleshooting.md).
## Commands at a glance
| Command | Purpose |
|---|---|
| `npx --yes eas-cli@latest simulator:start --platform ios\|android --name "<description>" [--type agent-device\|argent\|serve-sim] [--package-version X] [--max-duration-minutes N] [--non-interactive] [--json]` | Create a session; boot the sim + controller; write `.env.eas-simulator`; print `webPreviewUrl` + job-run URL. **Always pass `--name`** (see *Always name the session*). **`--json` suppresses the `.env.eas-simulator` write**, omit it for the `exec` flow, or set the env yourself from `remoteConfig`. |
| `npx --yes eas-cli@latest simulator:exec <cmd> [args…]` | Load `.env.eas-simulator`, then run `<cmd>` with that env. The bridge to the controller. |
| `npx --yes eas-cli@latest simulator:get [--id] [--json]` | Session status + connection details, including the session `--name`. **Use this to confirm readiness** (see *Operating principles*). |
| `npx --yes eas-cli@latest simulator:list [--status …] [--type …] [--platform …]` | List an app's sessions by name, this is what the `--name` you pass to `start` is for |
| `npx --yes eas-cli@latest simulator:stop [--id]` | Stop a session (idempotent) |
## Running the user's app, pick a modeFrom gmackie/agent-skills, MIT.
More from gmackie/agent-skills
- 0.529score
eas-observe
gmackie
EAS service (paid).
SkillBFreshness: BClaude Code +9 - 0.529score
eas-update-insights
gmackie
EAS service (paid).
SkillBFreshness: BClaude Code +9 - 0.529score
eas-workflows
gmackie
EAS service (paid).
SkillBFreshness: BClaude Code +9 - 0.524score
agent-skills-catalog-maintenance
gmackie
Use when adding, migrating, or reorganizing skills, tools, or agent definitions in an `agent-skills` style repo and you need to keep the catalog surface…
SkillBFreshness: BClaude Code +9 - 0.524score
brand-domain-naming
gmackie
Use when naming or renaming a product, startup, feature, or app and the work depends on brand identity, design culture, domain research, or TLD tradeoffs.
SkillBFreshness: BClaude Code +9 - 0.524score
cloudflare-d1-development
gmackie
Use when adding, debugging, or hardening Cloudflare D1 usage in a Workers app.
SkillBFreshness: BClaude Code +9 - 0.524score
cloudflare-workers-bindings-local-dev
gmackie
Use when setting up, debugging, or hardening local development for a Cloudflare Workers project that depends on bindings like D1, KV, R2, Queues, Durable…
SkillBFreshness: BClaude Code +9 - 0.524score
eas-hosting
gmackie
EAS service (paid).
SkillBFreshness: BClaude Code +9 - 0.504score
diagnosing-bugs
gmackie
Diagnosis loop for hard bugs and performance regressions.
SkillBFreshness: BClaude Code +9 - 0.501score
architect
gmackie
Sketch types, signatures, and module structure before code, then stay in the loop while implementation fills in.
SkillBFreshness: BClaude Code +9 - 0.501score
create-verification-skill
gmackie
Generate a project-local verification skill that drives your app the way a user does, in any language, framework, or platform.
SkillBFreshness: BClaude Code +9 - 0.499score
domain-modeling
gmackie
Build and sharpen a project's domain model.
SkillBFreshness: BClaude Code +9
Signals
- Stars
- 0
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Aug 26, 2026 (2 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/gmackie/agent-skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from gmackie
- 0.529score
eas-update-insights
gmackie
EAS service (paid).
SkillBFreshness: BClaude Code +9 - 0.529score
eas-observe
gmackie
EAS service (paid).
SkillBFreshness: BClaude Code +9 - 0.529score
eas-workflows
gmackie
EAS service (paid).
SkillBFreshness: BClaude Code +9 - 0.524score
cloudflare-d1-development
gmackie
Use when adding, debugging, or hardening Cloudflare D1 usage in a Workers app.
SkillBFreshness: BClaude Code +9 - 0.524score
brand-domain-naming
gmackie
Use when naming or renaming a product, startup, feature, or app and the work depends on brand identity, design culture, domain research, or TLD tradeoffs.
SkillBFreshness: BClaude Code +9 - 0.524score
agent-skills-catalog-maintenance
gmackie
Use when adding, migrating, or reorganizing skills, tools, or agent definitions in an `agent-skills` style repo and you need to keep the catalog surface…
SkillBFreshness: BClaude Code +9
Cite this page
eas-simulator skill. Agent Mart. https://agentmart.dev/skills/gmackie-eas-simulator (last updated 2026-10-24)