An Android emulator inside herdr. The emulator opens in a view next to your coding agent, so you and your agent use the same device, and the agent can read every log, crash and event the app produces. Its sibling, herdr-ios-simulator, does the same for iOS with the same commands.
Status: early development. The View, the agent CLI, logs, crashes and events work on macOS; Linux is untested. docs/FEATURES.md lists what's built and what's next.
Run Android: open from herdr, pick Android from herdr desktop's + menu, or let the agent run herdr-android boot --show. The emulator boots without its own window and appears in a herdr pane. Click to tap, drag to swipe, type to type. The header has Android's Back, Home and Recents buttons on the left, and Rotate, Send screenshot to agent and Power on the right; hover one to see its name.
herdr plugin install is all you run. Our installer checks for the Android SDK and downloads it if it's missing, along with a ready-to-boot device. You don't need Android Studio, only JDK 17 or later.
The agent builds with Gradle and gets back only the errors and warnings, with file:line. It installs and launches the app, lists what's on screen, and taps and types like you would. You watch it happen and can take over at any point.
logs returns the app's logcat, following it across restarts. crashes returns crashes and ANRs with their stacks, even from before the last reboot:
$ herdr-android crashes
22:49:46 boot 11 crash in dev.herdr.demo
java.lang.IllegalStateException: sign in failed: no email
at dev.herdr.demo.MainActivity.lambda$onCreate$1(MainActivity.java:53)
at android.view.View.performClick(View.java:8083)
events returns the device's timeline: boots, installs, launches, and your taps in the view. Nothing streams into the agent's context until it asks.
- macOS or Linux. On Linux, KVM (
/dev/kvm) for a usable emulator speed. - JDK 17 or later, for the Android SDK tools.
- Rust (
cargo), because herdr builds the plugin from source when it installs.
The install uses the Android SDK in ANDROID_HOME (or Android Studio's) if you have one, and installs one otherwise. Without herdr-default, it boots the AVD you used most recently, such as one from Android Studio. Booting an AVD sets hw.keyboard=yes in its config.ini, because the emulator ignores the View's typing and keys without a hardware keyboard.
herdr plugin install MattJColes/herdr-android-emulatorherdr shows the commands the plugin will run, then builds it with cargo build --release and sets it up:
- Links
herdr-androidinto~/.local/bin. - Runs
herdr-android install-sdk. This does nothing if you already have an SDK with an AVD, for example from Android Studio. Otherwise it downloads a few GB the first time. - Runs
herdr-android install-agents, which installs aherdr-androidskill or instructions for Claude Code, Codex, OpenCode and Pi, whichever you have. It also adds Android to herdr desktop's + menu.
If a step fails, for example because no JDK 17+ is found, the install still finishes and prints the fix; run that command again afterwards. With herdr desktop installed, herdr also re-runs install-agents each time it starts. herdr-android uninstall takes the agent setup back out.
herdr plugin update herdr-android-emulatorThis fetches the latest commit, rebuilds and re-runs the setup, so your agents learn any new commands. A running device keeps running, and a view that is already open keeps the old build; close it and open it again to get the new one.
herdr plugin uninstall herdr-android-emulatorThat unregisters the plugin but leaves its link, settings and recorded logs in place. To remove those too:
rm ~/.local/bin/herdr-android
rm -rf ~/.local/state/herdr/plugins/herdr-android-emulator
rm -rf ~/.config/herdr/plugins/config/herdr-android-emulatorinstall-agents also added a herdr-android section to your agents' instruction files; delete it by hand until herdr-android uninstall does it for you.
The Android SDK and your virtual devices stay, because Android Studio, Flutter and React Native use the same ones. To remove them too:
rm -rf ~/Library/Android/sdk ~/.android/avd # macOS
rm -rf ~/Android/Sdk ~/.android/avd # Linuxherdr-android boot --show # boot the default device and show it to the user
herdr-android build --run # errors/warnings with file:line, then install and launch
herdr-android ui # [4] Button "Sign in"
herdr-android tap 4
herdr-android type "hello" --submit
herdr-android mark before-login
herdr-android logs --errors --since before-login
herdr-android crashes
herdr-android screenshot /tmp/screen.pngherdr-android agent-help prints the full list. Add --json to any command for structured output, and --device emulator-5556 to pick a device when several are running.
| Input | What it does |
|---|---|
| Click | Tap |
| Drag | Swipe |
| Scroll wheel | Scroll |
| Typing, Return, Backspace, Tab | Sent to the focused field |
| Ctrl-B | Back |
| Ctrl-O | Home |
| Ctrl-X | Send a screenshot to the agent |
| Ctrl-Q | Close the view (the device keeps running) |
| Header buttons | Back, Home, Recents · Rotate, Send screenshot to agent, Power (shuts the device down) |
Optional. Put them in ~/.config/herdr/plugins/config/herdr-android-emulator/config.toml:
default_device = "herdr-default" # the AVD `boot` and the view use when nothing is running; unset: herdr-default, else your most recently used AVD
fps = 15 # live view frame rate, 1-30
view_renderer = "blocks" # if the view stays blank in your terminal
cell_aspect = 2.6 # if the device looks stretchedexamples/demo-app is a sign-in screen with two bugs to find: Sign in with no email crashes, and Freeze causes an ANR.
cd examples/demo-app
herdr-android boot --show
herdr-android build --rungit clone git@github.com:MattJColes/herdr-android-emulator.git
cd herdr-android-emulator
cargo build --release
herdr plugin link .
git config core.hooksPath .githooks # once per clone: fmt, clippy and tests before each commitherdr plugin link doesn't run build commands, so rebuild with cargo build --release after each change. CI runs cargo fmt, clippy and the tests on macOS and Linux for every pull request. Release Please opens a release PR from Conventional Commits. Words like Device, View and Current app are defined in GLOSSARY.md; decisions are in docs/adr.
MIT. See LICENSE.

