Develop

Make your existing app compatible with Meta Quest

Updated: Aug 28, 2026
Meta Horizon OS is built on AOSP, so existing mobile Android apps share the same foundation as apps for Meta Quest. This guide explains how to make your app compatible with Meta Quest 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 Quest, 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 Quest, 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>
Smallest size at which your app remains usable
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"
                android:minWidth="360dp"
                android:minHeight="225dp" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

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 Horizon 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.

Detect Horizon OS without a dependency

Use Android’s PackageManager.hasSystemFeature() method to check for the Horizon OS or standalone VR system feature. This procedure does not add a dependency to your app.
import android.content.Context

private const val FEATURE_HORIZON_OS = "horizonos.software.horizon_os"
private const val FEATURE_STANDALONE_VR = "oculus.hardware.standalone_vr"

fun isRunningOnHorizonOs(context: Context): Boolean {
    val packageManager = context.packageManager
    return packageManager.hasSystemFeature(FEATURE_HORIZON_OS) ||
        packageManager.hasSystemFeature(FEATURE_STANDALONE_VR)
}
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 headset-meaningless ones 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 Horizon Android Studio Plugin underlines unsupported libraries and permissions as you type.

Test in Meta Spatial Simulator

Test your existing app in a VR environment before completing final verification on a headset.
Meta Spatial Simulator is available in the Meta Horizon 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 headset 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 Quest, explore these features for VR:

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.