Skip to content

Emulator

wody edited this page May 24, 2026 · 5 revisions

Android Emulator

Introduced in v0.19.0 as scaffolding + diagnostics only. Full emulator automation with noVNC mirroring is reserved for a separate image variant (siamakerlab/vibe-coder-server:full) coming in v0.20+.

View at /emulator (left nav: "Emulator").

Why scaffolding-only in v0.19.0

The slim base image (~600 MB) ships JDK + Node + git + the server body — that's it. A full Android emulator needs:

  • KVM (/dev/kvm accessible inside the container) — host-specific
  • qemu-system-x86_64 + libs — ~400 MB
  • X server (Xvfb) + websockify + noVNC — ~150 MB
  • Android system-image — 1–2 GB depending on API level

Adding all of those to the default image triples its size for users who will never touch the emulator. The decision: keep the default slim, provide a :full variant for users who really want in-browser emulator mirroring, and let :default users still run an emulator on the host and use the diagnostics page to inspect it.

What /emulator shows in v0.19.0

EmulatorService.diagnose() runs at every page load and reports:

Item Source
KVM available /dev/kvm exists and is readable+writable
emulator binary $ANDROID_HOME/emulator/emulator
adb binary $ANDROID_HOME/platform-tools/adb
Installed AVDs avdmanager list avd -c
Running devices adb devices (drops the header)
Recommendation dynamic text — what to do next based on the above

Enabling KVM passthrough

By default the compose service runs unprivileged with no device access. KVM requires you to grant access:

services:
  vibe-coder-server:
    devices:
      - /dev/kvm:/dev/kvm
    # If running on a host where /dev/kvm is owned by the kvm group:
    group_add:
      - "${KVM_GID:-104}"   # adjust to match `getent group kvm | cut -d: -f3`

And ensure the host operator is in the kvm group:

sudo usermod -aG kvm $USER
# logout / login to take effect

Without KVM the emulator falls back to software emulation — usually 10× slower. Useful for one-off "did the layout render?" checks but not for realistic perf testing.

Manual launch flow (v0.19.0)

The /emulator page renders the full guide inline. Excerpts:

1. Install a system image

docker exec -it --user vibe vibe-coder-server bash
$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager 'system-images;android-35;google_apis;x86_64'
$ANDROID_HOME/cmdline-tools/latest/bin/avdmanager create avd \
    -n test \
    -k 'system-images;android-35;google_apis;x86_64'
exit

2. Start the emulator (headless)

docker exec -d --user vibe vibe-coder-server \
    bash -c '$ANDROID_HOME/emulator/emulator -avd test -no-window -no-audio &'

-no-window runs without a GUI — fine because v0.19.0 doesn't include the noVNC display anyway. ADB still works.

3. Verify and use

Refresh /emulator — the new device should appear under "Running devices".

To install a freshly built APK, ask Claude in the project console:

"Install the latest debug APK on the running emulator and launch the main activity."

Claude knows how to find the APK under <workspace>/.vibecoder/<projectId>/artifacts/debug/<buildId>/*.apk and adb install -r it. The internal EmulatorService.installApk(deviceSerial, apkPath) is also available for direct programmatic use.

Coming in v0.20+ (:full variant)

  • siamakerlab/vibe-coder-server:full Dockerfile — adds qemu, Xvfb, websockify, noVNC, default system-image.
  • /emulator gets a "Launch AVD" button + an iframe to /emulator/vnc/.
  • AVD lifecycle (create / start / stop / wipe) via REST API.
  • ADB log streaming via WebSocket.
  • Multi-AVD parallel sessions (one per project).

Track the work in CHANGELOG ### Phase 5 follow-up.

Alternatives in the meantime

  • Host emulator — install Android Studio on the host, run an AVD there, ADB-connect to the container if needed (adb connect host.docker.internal:5555 after enabling ADB-over-TCP).
  • Physical device — uncomment the devices: - /dev/bus/usb:/dev/bus/usb block in compose.yml and adb devices will pick it up.
  • Cloud emulator (Firebase Test Lab, AWS Device Farm, Genymotion Cloud) — out of scope for vibe-coder; the operator runs builds + uploads manually for now.

Clone this wiki locally