Guides porting existing Android 2D apps to Meta Quest and Horizon OS — input adaptation, panel layout, and design requirements. Use when adapting a mobile Android app for Quest.
npx skills add https://github.com/meta-quest/agentic-tools --skill hz-android-2d-porting
Use this skill when:
Horizon OS is built on Android (AOSP) and can run standard Android applications inside panels -- floating 2D windows positioned in 3D space. Most well-built Android apps work on Quest with minimal changes, but several areas require attention:
The goal of porting is to make the app feel native to the Quest experience while preserving existing functionality.
Invoke metavr (the Quest device CLI) via metavr <args>. The command is published as the npm package metavr, so if metavr is not on PATH you can run the same CLI via npx -y metavr <args> — no global install needed; npx fetches the latest published version on demand.
The examples in this doc call metavr directly; the npx -y metavr <args> form above is the equivalent when metavr is not on PATH (the published npm package is still metavr).
Install the existing APK on a connected Quest device and test basic functionality:
metavr app install path/to/your-app.apk
metavr app launch com.example.yourapp
Note any immediate issues: crashes, black screens, input problems, or layout breakage.
The most common porting issue is input. Touch events are translated from the controller pointer, but:
See Input Adaptation Reference for detailed guidance.
Panels are resizable and can have various aspect ratios. Your app must handle:
Use responsive layout strategies such as ConstraintLayout or Jetpack Compose. See Panel Layout Reference.
Update your build configuration to target Horizon OS:
// build.gradle.kts
android {
defaultConfig {
minSdk = 29 // Android 10 minimum
targetSdk = 34 // API 34 or higher required for all new 2D panel apps
}
}
Add required manifest entries for device targeting. See Gradle Setup Reference.
Test with all supported input methods:
Use the XR Simulator for rapid iteration, then validate on-device.
Before submitting to the Horizon Store:
| Feature | Status | Notes |
|---|---|---|
| Standard Android Views | Supported | TextView, RecyclerView, etc. |
| Jetpack Compose | Supported | Full Compose UI toolkit |
| WebView | Supported | Chromium-based |
| Media playback (ExoPlayer) | Supported | Video and audio |
| Networking (HTTP, WebSocket) | Supported | Wi-Fi connectivity |
| Room / SQLite | Supported | Local database |
| WorkManager | Supported | Background tasks |
| Notifications | Supported | Horizon OS notification panel |
| Bluetooth (peripherals) | Supported | Keyboard, mouse, gamepad |
| Android Accessibility APIs | Supported | TalkBack equivalent available |
| Feature | Status | Notes |
|---|---|---|
| Camera (front-facing) | Not available | No standard camera in 2D mode |
| Telephony / SMS | Not available | No cellular radio |
| NFC | Not available | No NFC hardware |
| GPS / Fine location | Limited | Wi-Fi-based location only |
| Fingerprint / BiometricPrompt | Not available | Use Meta account auth instead |
| Split-screen (multi-window) | Limited | Use Spatial SDK panels instead |
| Google Play Services | Not available | Use Meta equivalents or alternatives |
| ARCore | Not available | Use Meta Spatial SDK for spatial features |
| Multi-touch gestures | Limited | Single pointer from controller |
| Issue | Cause | Fix |
|---|---|---|
| App crashes on launch | Missing Google Play Services dependency | Remove or make GMS optional |
| Buttons too small to tap | Touch targets under 48dp | Increase minimum tap target size |
| No scroll in lists | Swipe-based scroll not triggered | Ensure RecyclerView/LazyColumn handles generic scroll events |
| Keyboard doesn't appear | Custom input field not using InputConnection | Use standard EditText or TextField |
| Layout broken | Fixed-size layout assumptions | Use responsive layouts with ConstraintLayout or Compose |
| App requests unavailable permissions | Camera, telephony, etc. | Guard with hasSystemFeature() checks |
| APK rejected for prohibited permissions | Library or plugin silently added a prohibited permission | Run aapt dump permissions your-app.apk, then check prohibited list |
| APK rejected for invalid signature | Signed with v1-only scheme | v2 signing is default in AGP 7.0+; for older AGP, add v2SigningEnabled = true to your signing config |
Apps not specifically targeting Horizon OS run in compatibility mode:
Apps that target Horizon OS with proper manifest entries run in native mode:
Quest devices have mobile-class hardware with strict thermal limits:
Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts.
Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts.
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.
Set up Tailwind CSS v4 in Expo with react-native-css and NativeWind v5 for universal styling
Use Expo DOM components to run web code in a webview on native and as-is on web. Migrate web code to native incrementally.
Take meta-quest/hz-android-2d-porting from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npx.
Without those the skill loads but fails at the first command.