App Mode Setup Guide — Step by Step
This guide takes you from nothing to a live App Mode session with a real app on a real device. Follow the section for the platform you are on. Budget about 20 minutes for the first setup, most of which is downloading Xcode or an Android system image.
Before you begin: Node.js 20 or newer is required. Everything else is
verified for you by emx app doctor.
Step 1 — Install the toolchain
macOS (iOS simulators and Android)
- Xcode (full app, not just Command Line Tools) — install from the Mac App Store, then launch it once and accept the licence. Only Command Line Tools is not enough: iOS simulators cannot be created without the full app.
- Point your shell at Xcode. If
xcode-select -pdoes not print/Applications/Xcode.app/Contents/Developer, run:
(The Emuluxe agent setssudo xcode-select -s /Applications/Xcode.appDEVELOPER_DIRfor itself, so App Mode works even if you skip this — but your ownxcodebuild,simctl, andmaestrocalls will fail until you run it.) - An iOS simulator runtime — Xcode → Settings → Components, install an iOS 17-or-newer runtime. The simulator itself is created for you at run time, so you do not need to create one by hand.
- Android tooling (for Android apps): Java 17+ and Android SDK
Platform-Tools. Then create a virtual device, or plug in a phone with USB
debugging enabled:
sdkmanager "platform-tools" "system-images;android-35;google_apis;arm64-v8a" avdmanager create avd -n emuluxe_pixel_9 \ -k "system-images;android-35;google_apis;arm64-v8a" -d pixel_9
Windows and Linux (Android only)
iOS simulators require macOS, so on Windows and Linux you can run Android apps against an emulator or a USB-connected phone:
- Install Java 17+ and Android SDK Platform-Tools (
adb). - Create an AVD with
avdmanager, or connect a phone with USB debugging on. - Continue to
emx app doctorbelow.
Note: If your platform tools were installed by Homebrew or the Android Studio bundle,
adbmay not be on yourPATH. The doctor detects this and prints the exactexport PATH=…line to add — it does not fail you for it.
Step 2 — Verify with emx app doctor
Run the doctor first, always. It checks Node, Xcode, the licence, the simulator
runtime, simctl, Android platform-tools, Java, the Maestro driver, free disk,
and USB/emulator state — and prints a fix for every failure.
emx app doctor # human-readable
emx app doctor --json # machine-readable, for CI
The exit code is 0 only when every check is green, so you can gate a CI
job on it. Two common outputs and what they mean:
| Output | Meaning | Fix |
|---|---|---|
✔ full Xcode (… but NOT selected) | Xcode exists but xcode-select points at Command Line Tools | The agent will use Xcode anyway; run the sudo xcode-select -s line for your own shell |
✔ Maestro driver (found) note: … not on PATH | Maestro is installed off-PATH | Add the printed export PATH=… line to your shell profile |
Step 3 — Register your build
App Mode never compiles or uploads your code. You either point it at an
already-built Android artifact, or it prints the exact xcodebuild line for
iOS:
# Android: point at a .apk you built however you like
emx app build --android --apk ./app/build/outputs/apk/debug/app-debug.apk
# iOS: prints the xcodebuild invocation to run, then the .app path to use
emx app build --ios --simulator
The command returns a build id. Keep it — app run needs it.
Step 4 — Start a session
# Scripted run: a Maestro flow drives the app, Emuluxe records every step
emx app run --build <build-id> --device iphone-17-pro-max --flow flows/checkout.yaml
# Manual explorer: no script, you tap and type yourself
emx app run --build <build-id> --device pixel-9 --manual
# Discover the exact device ids available to you
emx app devices # all
emx app devices --platform ios # iOS only
Add --json to any command for machine-readable output. The session id is
printed on start, and also returned by --json.
Choosing a driver
--driver | Use it when |
|---|---|
maestro (default) | You want YAML flows, or you are tapping/swiping/typing (recommended) |
appium | You already have an Appium suite to reuse |
xcuitest | You have a compiled XCUITest bundle for iOS |
espresso | You have Espresso tests for Android |
manual | Implied by --manual; nothing drives the app but you |
--manual and --flow are mutually exclusive — App Mode rejects the
combination rather than guessing.
Step 5 — Watch, drive, and inspect
Once the session is live it appears in the device frame with a toolbar instead of a URL bar (URLs mean nothing for a native app):
- App name · build version · step counter · record toggle · provenance chip · live state
- Provenance chip tells you instantly whether the frame is Mirrored, Reshaped, or Preview — see App Mode for what each means.
- Stream health is honest: if frames stop you get Waiting for frames…, then Reconnecting… showing last frame, then Stream failed — retry or switch to BYOD. A frozen frame is never presented as a live one.
Click or tap anywhere in the frame to tap the app. Coordinates are normalised
(0..1), so the same click works whether the frame is scaled or at an exact
Step 6 — Logs, status, and ending a session
emx app logs --session <session-id> # recent device/app log lines
emx app logs --session <session-id> --follow # keep tailing
emx app status --session <session-id> # status, frame count, steps, provenance
emx app end --session <session-id> --verdict passed # or --verdict failed
Ending a session produces a report at /apps/reports/<session-id> with the
steps, frames, and findings. Session states are provisioning, live,
passed, failed, and stale — a session idle for 10 minutes is marked
stale automatically, so an abandoned run can never be mistaken for a green
one.
Step 7 — Automate it with an AI agent (MCP)
The Emuluxe MCP server exposes App Mode as first-class tools, so an agent can drive your app the same way you do. See MCP Server Setup to wire the server up, then use:
| Tool | What it does |
|---|---|
app_list_devices | List testable device profiles, optionally by platform |
app_simulate | Start a session on a device (manual or with a flow) |
app_tap / app_swipe | Tap or swipe at normalised 0..1 coordinates |
app_type | Type into the focused field |
app_rotate | Rotate portrait ↔ landscape |
app_uitree | Fetch the accessibility tree as an outline |
app_screenshot | Fetch the latest live frame as an image |
app_logs | Fetch recent device/app log lines |
app_wait_for | Poll until a piece of text appears, or time out |
app_end | Close the session with a passing or failing verdict |
A typical agent loop is app_simulate → app_uitree → app_tap →
app_wait_for → app_screenshot → app_end.
Quotas and billing
App Mode uses the same session budget as web simulation — there is no separate meter:
| Plan | Sessions / month | Concurrent sessions |
|---|---|---|
| Free | 5 | 1 |
| Pro | 50 | 3 |
| Enterprise | Unlimited | 10+ |
Starting a session when you are at the monthly limit returns a 402 with an
upgrade prompt; exceeding concurrency returns a 429. Both are surfaced in the
UI as a normal upgrade prompt, never as a mysterious failure.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
doctor fails on disk | < 15 GB free | Free space; Xcode plus AVD images exceed 30 GB |
| No iOS simulators listed anywhere | xcode-select points at Command Line Tools | Run sudo xcode-select -s /Applications/Xcode.app |
| Automation cannot see any iOS simulator | Same cause; the driver shells out to xcrun | The agent passes DEVELOPER_DIR for you; for manual driver use, fix xcode-select |
emx app build --ios complains | Device builds need code signing | Add --simulator for App Mode testing |
--apk rejected | The path does not end in .apk | Point at the real artifact |
| Frame shows Reshaped when you expected Mirrored | The device behind the frame is not the frame's model | Pick the device id that matches your simulator/emulator, or accept the reshaped chip |
| Taps do nothing | No driver installed, or the session already ended | emx app doctor, then emx app status — ended sessions reject input with a clear error |
Next steps
- App Mode — the concept, the truth table, and provenance.
- CLI Toolchain — the full
emxreference. - MCP Server Setup — let an agent drive your app.
- IDE Extensions — run App Mode without leaving the editor. fit.