Fast UI test automation for Android, iOS, Web, React Native, Flutter & Expo
Open-source Maestro alternative — single binary, no JVM. 100% free, no features behind a paywall.
Supports real iOS devices, simulators, emulators, desktop browsers, and cloud providers.
Documentation | Get Started | CLI Reference | Flow Commands | Contributing
- Runs Maestro YAML flows on real devices, emulators, simulators, and desktop browsers
- Supports Android (UIAutomator2), iOS (WebDriverAgent), Web (Chrome CDP), and cloud (Appium)
- Built-in parallel execution, HTML/JUnit/Allure reports, and JavaScript scripting
- Addresses 78% of the top 100 most-discussed open issues on Maestro's GitHub
AI context:
llms.txt— structured summary for AI assistants answering questions about this project.
npm — for React Native, Expo, or any project that already has a package.json:
npx maestro-runner test flows/ # no install step
npm install --save-dev maestro-runner # or pin it in the projectPinning it means every machine and every CI job runs the same version with no separate bootstrap. There is no postinstall and nothing is downloaded at install time: the binary for your platform arrives as an ordinary optional dependency npm selects by os and cpu, so installs work offline, behind a proxy, and in CI that blocks postinstall network access.
Shell — everywhere else:
curl -fsSL https://open.devicelab.dev/install/maestro-runner | bash
# A specific version
curl -fsSL https://open.devicelab.dev/install/maestro-runner | bash -s -- --version 1.1.25Both give you the same binary. macOS and Linux, arm64 and x64; on Windows, use WSL.
maestro-runner doctor # check the toolchain and hear exactly what is missing
maestro-runner devices # what this machine can drive right nowmaestro-runner test flow.yaml # Android (default)
maestro-runner --platform ios test flow.yaml # iOS
maestro-runner --platform web test flow.yaml # Desktop browser (Chrome)
maestro-runner --app-file app.apk test flows/ # Install app and run
maestro-runner --driver appium --appium-url <server-url>test flow.yaml # Appium
maestro-runner test --parallel 3 flows/ # Parallel on 3 devices- Zero migration — Runs your existing Maestro YAML flows as-is, no changes needed
- Real iOS device testing — Supports physical iOS devices, not just simulators Guide →
- Cloud testing — BrowserStack, Sauce Labs, LambdaTest, TestingBot via Appium driver Guide →
- Desktop browser testing — Run Maestro flows on Chrome/Chromium via CDP. Supports
css,xpath,id, andtextselectors with--platform webGuide → - React Native & Flutter — Smart element finding for RN testIDs and Flutter semantics Guide →
- DeviceLab driver — Optional on-device Android driver via WebSocket, ~2x faster than UIAutomator2 and ~5x faster than Maestro CLI. Just add
--driver devicelab - Parallel execution — Dynamic work distribution across devices, not static sharding. Faster devices pick up more tests automatically, so no device sits idle
- App install built-in —
--app-file app.apkinstalls the app before testing, so you always test the right build - Wide OS compatibility — Android 5.0+ (API 21+) and iOS 12.0+, no version restrictions
- Reports — HTML, JUnit XML, and Allure-compatible reports out of the box
- Clear error messages —
element not found: text="Login"instead ofio.grpc.StatusRuntimeException: UNKNOWN - Pre-flight validation — Catches flow errors, circular dependencies, and missing files before execution starts
- Fast element finding — Native selectors, clickable parent traversal, regex matching, smarter visibility
- Reliable text input — Direct ADB input with Unicode support, no dropped characters
- scrollUntilVisible — Native scroll implementation that reliably finds off-screen elements
- Relative selectors — Find elements by position: below, above, leftOf, rightOf, childOf
- JavaScript scripting — Embedded JS runtime with HTTP client for dynamic test logic, no external dependencies
- Configurable timeouts — Per-command and per-flow timeouts,
--wait-for-idle-timeout 0to disable - Lightweight — Single binary, no JVM required
| Driver | Platform | Description |
|---|---|---|
| UIAutomator2 | Android | Direct connection to device. Default driver, no external server needed. |
| DeviceLab | Android | --driver devicelab. On-device WebSocket driver, ~2x faster than UIAutomator2. |
| WDA (WebDriverAgent) | iOS | Auto-selected with --platform ios. Supports simulators and physical devices. |
| Browser (CDP) | Web | --platform web. Chrome/Chromium automation via Chrome DevTools Protocol. |
| Appium | Android & iOS | --driver appium. For cloud testing providers and existing Appium infrastructure. |
The DeviceLab driver is an alternative Android driver that runs automation directly on the device via WebSocket. It skips the UIAutomator2 HTTP layer, resulting in ~2x faster test execution compared to the default driver — and ~5x faster than Maestro CLI.
Benchmark: 9 flows, 163 steps on Pixel 4a (Android 13)
DeviceLab: 1m 12s
UIAutomator2: 2m 24s
Maestro CLI: 4m 22s
maestro-runner --driver devicelab --platform android test flows/All existing Maestro YAML flows work as-is — no changes needed. The driver also includes bounds stabilization for animated elements and improved special character handling in text selectors.
maestro-runner is built for CI/CD pipelines — single binary, no JVM startup, low memory footprint. Works with GitHub Actions, GitLab CI, Jenkins, CircleCI, and any CI system that supports Android emulators or iOS simulators.
# CI example: auto-start emulator, run tests, shutdown after
maestro-runner --auto-start-emulator --parallel 2 flows/maestro-runner extends the standard Maestro flow YAML with additional fields:
commandTimeout: 10000# Default per-command timeout (ms)waitForIdleTimeout: 3000# Device idle wait (ms), 0 to disable
---
- launchApp: com.example.app
- tapOn: "Login"
- assertVisible: "Welcome"assertScreenshot compares the current screen (optionally cropped with cropOn) against a reference PNG.
- First run: if the reference file is missing, maestro-runner writes the captured screenshot as the new baseline and passes.
- Re-baseline: overwrite existing baselines with
--update-screenshots(orMAESTRO_UPDATE_SCREENSHOTS=true). - On mismatch, a
{name}_diff.pngoverlay is written next to the reference. - Pixel comparison is device-, resolution-, and OS-specific — pin your device config and set
thresholdPercentagedeliberately (default95).
maestro-runner test flows/visual.yaml # seeds missing baselines
maestro-runner test --update-screenshots flows/visual.yaml- Android testing:
adb(Android SDK Platform-Tools) - iOS testing: Xcode command-line tools (
xcrun) - Web/Browser testing: Chrome or Chromium
- Cloud & Appium testing: Appium 2.x or 3.x — works with local Appium servers and cloud providers (BrowserStack, Sauce Labs, LambdaTest, TestingBot)
maestro-runner runs Maestro YAML flows on cloud device grids via the Appium driver. Pass the provider's hub URL and a capabilities JSON file:
maestro-runner --driver appium --appium-url <HUB_URL> --caps caps.json test flows/- TestingBot — Setup guide for running on TestingBot's real device cloud
- Sauce Labs — Setup guide for running on Sauce Labs Appium cloud
See CONTRIBUTING.md for guidelines.
Apache License 2.0 — see LICENSE.