OpenVM is a local-first, open-source Android VM control plane inspired by the isolation and multi-instance workflow of VMOS. It is written from scratch and does not copy VMOS code, assets, branding, or private services.
Status: the repository is a working open-source runtime milestone. It creates and stores VM profiles, validates a strict guest-image manifest against the selected profile and image/boot-artifact digests, materializes selected guest assets into app-private storage, can use a workflow-built QEMU runtime from Android's native-library directory or an explicitly imported executable, exposes a private UNIX-socket framebuffer transport with bounded touch/key input, exports configuration, records local history, exposes an honest AVF readiness panel, and ships reproducible unsigned GitHub Actions APK/AAB artifacts. The bundled native lane is experimental and has not yet proved an Android guest boot, serial console, or file transfer.
- What is implemented
- Architecture
- Build locally
- Unsigned release artifacts
- Security boundary
- Project documentation
- License
- VM profile creation and editing with validation for memory, storage, vCPU count, architecture, and guest Android version.
- Android Storage Access Framework import for a user-selected guest image; OpenVM stores the persisted content URI and materializes a bounded private copy only when a QEMU profile is started. It never uploads the image.
- Versioned guest-image manifest import with strict JSON, architecture/machine pairing, raw-disk metadata, SHA-256/size verification, and explicit disk-only or kernel-initrd boot contracts.
- Local JSON configuration import/export.
- Local append-only history for profile creation, editing, deletion, import, and export.
- Multiple profile cards with truthful lifecycle states. QEMU starts only after a bundled or imported executable, manifest, and bootable image are available; AVF remains explicitly unavailable until its platform adapter is verified. There is no fake “running” state.
- An open native QEMU build lane pinned to QEMU 11.0.3, the exact Termux Android patch revision, immutable Termux builder image, host ABIs, versioned runtime library closure, 16 KiB ELF contract, APK/AAB packaging contract, and required-runtime emulator probes. The lane never commits QEMU source or generated binaries.
- A process-backed QEMU adapter with ELF/path checks, bounded image and executable materialization, deterministic TCG command construction, serial output capture, stop timeouts, and explicit exit states.
- A private UNIX-domain VNC/RFB framebuffer transport attached to running QEMU profiles; it is local-only, renders the guest display, and sends bounded touch/key events without opening a TCP listener. It still makes no boot-readiness claim.
- Explicit QEMU kernel/initrd argument construction for manifests that select the
kernel-initrdcontract; boot artifacts are size/hash checked, stay app-private, and are never passed through a shell. - Backend readiness reporting for Android Virtualization Framework and QEMU asset configuration.
- Profile/history search with an adjacent regex builder, bounded patterns, supported flags, live validation, and sample matching.
- Settings for language mode (English, playful Hong Kong-style Cantonese, or bilingual), independent funny-level sliders, emoji decoration, display name, and dark theme.
Ctrl+Shift+Fcommand palette for keyboard users.
The Google Play listing describes VMOS as supporting isolated Android systems, multiple virtual machines, background operation, configuration changes, and host↔guest file transfer. OpenVM's architecture keeps those goals separate: the Android UI/control plane is this project, while a native QEMU or AVF guest engine must be audited and built as its own open-source component.
Android UI
├── VM profiles + local JSON store
├── Storage Access Framework image references
├── local history and export
└── RuntimeBackendRegistry
├── AVF adapter boundary (Android 13+ capability check)
└── QemuRuntimeController
├── packaged native-library runtime or explicit imported executable
├── app-private asset materialization
├── strict guest-image manifest and integrity gate
├── deterministic QEMU process lifecycle
├── bounded serial diagnostics
└── local UNIX-socket VNC framebuffer client with bounded input
The boundary is deliberate. Android's VirtualizationService manages crosvm guests, but access depends on device and platform capabilities. QEMU is built from open-source upstream inputs, but a normal app must not claim full guest execution without a compatible executable, bootable image, display transport, permissions, and runtime verification.
Requirements:
- JDK 17 or newer supported by the Android Gradle Plugin.
- Android SDK 35 and build-tools installed.
- Network access for the first Gradle dependency resolution.
./gradlew testDebugUnitTest assembleDebug assembleDebugAndroidTest
py -3 scripts/verify_unsigned_android_artifacts.py app/build/outputs/apkThe debug app APK is written to
app/build/outputs/apk/debug/app-debug-unsigned.apk; the instrumentation package is
also built unsigned and inspected without installing it.
The optional native QEMU lane additionally needs Linux, Docker, jq, curl, readelf,
and sha256sum; GitHub Actions provides that environment. It targets Android API 29+
for bundled native execution. Run
native/qemu/build-android.sh --verify-only to validate the checked-in source and
patch pins without creating a runtime locally.
OpenVM intentionally does not generate, store, or use a code-signing certificate. Both Android build types explicitly clear their signing configuration. GitHub Actions builds reproducible unsigned APK/AAB artifacts, checks their QEMU contents and alignment, rejects JAR signatures, APK Signing Blocks, detached signatures, generated signing material, and symbolic-link escapes, validates AAB semantics with pinned bundletool, and publishes only post-verification staged packages plus checksums. Stock Android refuses to install an unsigned APK; this project does not supply the signing identity installation would require. See Android build and unsigned release artifacts.
OpenVM is local-first and has no account or telemetry service. Guest images, boot artifacts, and the imported QEMU executable are user-supplied code, so importing them is an explicit user action and they run with the OpenVM process permissions. The QEMU adapter enforces profile resource bounds, collision-resistant private asset paths, bounded copying, manifest/image/kernel/initrd integrity, lifecycle cleanup, and explicit process errors; its VNC framebuffer transport uses a private UNIX-domain socket and never opens a TCP listener. It does not grant the guest additional Android permissions.
Do not open issues or pull requests containing passwords, access tokens, private build inputs, or guest images. Report security issues through the process in SECURITY.md.
- VM profiles
- Guest-image manifest
- QEMU runtime adapter
- Native QEMU build lane
- Search and regex builder
- Unsigned Android artifacts
- Roadmap
- Handoff
This repository carries a sanitized project-local mirror in AGENTS.md. It is a mirror for contributors, not the canonical instruction source.
OpenVM's original code is licensed under the Apache License 2.0. Native runtime components added later must retain their own upstream licenses and notices; a GPL-licensed QEMU component cannot be relabeled as Apache-2.0.