Develop

Make your existing app compatible with Meta VR devices

Updated: Sep 14, 2026
Meta Horizon OS is built on AOSP, so existing mobile Android apps share the same foundation as apps for Meta VR devices. This guide explains how to make your app compatible with Meta VR devices while using a single build across Horizon OS and other Android platforms.

In this guide

Use AI to make your app compatible

For an AI-assisted workflow, configure Meta VR CLI for your AI coding tool, then use the hz-android-2d-porting agentic skill⁠. The skill analyzes your existing Android project, proposes the changes needed for Meta VR devices, and helps you build and test the result.
You can use the skill to guide the process or follow the sections below for the exact requirements and manual steps.

Manifest requirements

To make your existing app compatible with Meta VR devices, update its AndroidManifest.xml with the required Horizon OS tags and metadata:
AreaManifest declarationWhy it matters
Supported devices
<meta-data android:name="com.oculus.supportedDevices" android:value="quest2|questpro|quest3|quest3s" />
Declares supported Quest devices
Default window size
android:defaultWidth="1024dp" android:defaultHeight="640dp" inside <layout>
Initial size of your resizable app window
Minimum window size
android:minWidth="360dp" android:minHeight="225dp" inside <layout>
Optional. Set a floor only if your layout breaks below a certain size.
Orientation and display
android:screenOrientation and window metadata
Handles window resizing and immersive display
Example manifest snippet:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
        <meta-data
            android:name="com.oculus.supportedDevices"
            android:value="quest2|questpro|quest3|quest3s" />
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <layout
                android:defaultWidth="1024dp"
                android:defaultHeight="640dp" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
Optionally, add the uses-metavr-sdk element to declare the minimum and target Meta VR OS SDK versions your app supports. See Meta VR OS SDK versioning for details.

Run one codebase on multiple platforms

If your project also targets other Android platforms, isolate Horizon OS-specific code from your other Android builds. This keeps unsupported libraries and permissions out of your Horizon OS build.
ApproachBest for
Product flavors
Apps that want to completely remove unsupported code and dependencies from the Horizon OS build at compile time.
Runtime detection
Apps or libraries that need a single build artifact for Horizon OS and other Android platforms.

Option 1: Product flavors – separate APKs

Build separate APKs per device family. Each flavor (app/src/quest/, app/src/mobile/) has its own manifest and dependencies merged with main at compile time.
The following declares flavor-specific dependencies—for example, use mobileImplementation for Google Play Billing and questImplementation for Horizon Billing. The Meta VR Android Studio Plugin can generate this structure for you.
// app/build.gradle.kts
dependencies {
    "mobileImplementation"(libs.gms.billing)
    "questImplementation"(libs.horizon.billing.compatibility)
}
Keep common code in app/src/main/ and flavor-specific code in app/src/quest/ and app/src/mobile/. For example, keep BillingUser.kt in main and provide quest/java/Billing.kt using Horizon Billing and mobile/java/Billing.kt using Google Play Billing with the same interface.
For manifests, put Horizon OS metadata in quest/AndroidManifest.xml, mobile-only permissions in mobile/AndroidManifest.xml, and shared declarations in main/AndroidManifest.xml.
See Android’s product flavors⁠ and manifest merge⁠ guides.

Option 2: Runtime detection – single APK

Checking whether your app is running on Horizon OS can be an alternative to creating a separate product flavor. Instead of eliminating unsupported dependencies from the build, you can avoid calling code that does not work on Horizon OS. This lets you produce a single build for Horizon OS and other Android platforms.

Get the library

The Meta VR OS Utility Library is available from Maven Central⁠. Add the library to app/build.gradle.kts:
// app/build.gradle.kts
dependencies {
    implementation("com.meta.metavrx.util:util:1.0.0")
}

Perform the runtime check

Once the Meta VR OS Utility Library has been added as a dependency, call HorizonOsDetector.isOnHorizonOs() to detect Horizon OS at runtime. Pass it an Android Context⁠.
import metavrx.os.HorizonOsDetector;

if (HorizonOsDetector.isOnHorizonOs(context)) {
    // Execute code that only works on Horizon OS
} else {
    // Execute code that does not work on Horizon OS
}
Use this check to guard the entire call chain to an unsupported dependency so its classes are never loaded on Horizon OS.

Unsupported dependencies

Horizon OS does not include Google Mobile Services⁠, so calls into GMS APIs fail. Here are recommended replacements for popular services:
GMS dependencyReplacement
gms.auth (Sign-In)
gms.location
gms.ads.identifier (Ad ID)
billingclient.api
Android Notifications
The Horizon Billing Compatibility SDK follows the Google Play Billing API from a different package, which can simplify compatibility abstractions across builds. For user management, notifications, sharing, and other ecosystem features, see the Platform SDK overview.

Firebase

Horizon OS supports all Firebase dependencies that do not require Google Mobile Services. See Dependencies of Firebase Android SDKs on Google Play Services⁠ for more information.
Firebase libraryReplacement
App Check Play Integrity provider
App Check SafetyNet provider
App Indexing
Dynamic Links
Cloud Messaging
ML Vision
None
ML Custom Model
None

Unsupported permissions

Horizon OS prohibits many Android permissions—dangerous ones like INSTALL_PACKAGES or ones with no meaning on a Meta VR device, like CALL_PHONE. A build that requests a prohibited permission fails store upload. Other permissions are allowed after review; you explain the use case at submission.
For the complete lists, see Prohibited Android permissions and Review-requiring Android permissions. Remove prohibited permissions from AndroidManifest.xml before you build. The Meta VR Android Studio Plugin underlines unsupported libraries and permissions as you type.

Eye tracking permissions and Look and Pinch

When using Look and Pinch, don’t request eye tracking permissions—the system handles gaze and sends standard touch events. Remove these if present:
<!-- Do NOT include -->
<uses-permission android:name="com.oculus.permission.EYE_TRACKING" />
<uses-permission android:name="horizonos.permission.EYE_TRACKING" />
An app that requests them fails the Look and Pinch review. Hybrid apps that need eye tracking in immersive mode must declare the permission but only request it at runtime when the immersive activity launches. See Look and Pinch for 2D apps.

Test in Meta Spatial Simulator

Test your existing app in a VR environment before completing final verification on a physical device.
Meta Spatial Simulator is available in the Meta VR Android Studio Plugin or Meta VR CLI and renders your panel in a VR environment.
To test with the plugin, open your app, select the Meta Spatial Simulator device, and click Run.
To test from the command line, download and start the simulator, then install and launch your APK:
metavr ssim download
metavr ssim start
metavr app install path/to/app.apk
metavr app launch your.package.name
Meta VR CLI does not build your app. Build the APK with Android Studio or Gradle before you install it. Both workflows launch the same APK you would install on a physical device and let you verify resizing, input, and window configuration. For complete setup and debugging guidance, see Test on simulator.

Enhance your app

After your existing app runs on Meta VR devices, explore these features for VR:

Look and Pinch

Look and Pinch uses your app’s UI structure, text, and buttons to deliver standard input events. Test your app with Meta Spatial Simulator and follow the Look and Pinch design guidance, including using touch targets that are at least 48dp.
For special scenarios such as hover effects, use the Gaze SDK for Jetpack Compose.

Troubleshooting

Product-flavor files appear unresolved

Android Studio analyzes only the active product flavor. Open the Build Variants tool window, switch to questDebug or mobileDebug, and allow Gradle to sync again.

The Horizon OS build includes mobile-only dependencies

Declare platform-specific dependencies with questImplementation or mobileImplementation instead of implementation.