Integrating ViroReact with Expo

Installation instructions

🚧

ViroReact does NOT work with Expo Go

You must use a development client or expo prebuild to run an application using ViroReact.

After installing the package, add the config plugin to the plugins array of your app.json or app.config.js. Then rebuild your app as described in the "Adding custom native code" guide.

In your app.json plugins array:

{
  ... 
  "plugins": ["@reactvision/react-viro"]
}

Android Options

Using AR and/or QUEST on Android

The default option is ["AR"].

ViroReact supports two Android XR modes:

  • AR — ARCore on Android phones and tablets (default).
  • QUEST — immersive VR on Meta Quest devices via Horizon OS / OpenXR.
    You can ship them together — the same APK runs as a normal AR app on phones and as an immersive VR app on Quest. ViroReact's isQuest runtime helper distinguishes between them at runtime.

VR (Quest) requires Expo SDK 55 / React Native 0.83 or higher. AR continues to work on Expo SDK 54+. If your app is AR-only you can stay on Expo 54; if you need Quest support, upgrade. ViroXRSceneNavigator enforces this at runtime — on Quest hardware with RN < 0.83 it throws an actionable error and refuses to launch VR.

To change the XR mode on Android, configure the plugin in app.json / app.config.ts:

Using one other option
{
  ...
  "plugins": [
    [
      "@reactvision/react-viro",
      {
        "android": {
          "xRMode": "QUEST" // or "AR"
        }
      }
    ]
  ]
}
Using multiple options
{
  ...
  "plugins": [
    [
      "@reactvision/react-viro",
      {
        "android": {
          "xRMode": ["AR", "QUEST"],
          "questAppId": "YOUR_META_APP_ID"
        }
      }
    ]
  ]
}

Quest-specific configuration

When QUEST is included in xRMode, set questAppId to the numeric App ID from the Meta Developer Portal. The plugin writes it to AndroidManifest.xml as com.oculus.app_id meta-data, which tells Horizon OS the app name to display in system overlays. Without it the OS shows "App Name Unavailable" with a Quit button on first launch.

You don't need to edit AndroidManifest.xml by hand — the Expo plugin generates the required <activity> entry for VRActivity (declaring com.oculus.intent.category.VR) and the com.oculus.app_id meta-data automatically.

iOS options

There are 4 InfoPlist strings that are required for applications using Viro. ViroReact provides app.config level configuration for these InfoPlist strings and defaults for expo projects.

{
 ...
 "plugins": [
    [
      "@reactvision/react-viro",
      {
        "ios": {
        	"cameraUsagePermission": "$(PRODUCT_NAME) uses your camera for AR experiences. This is a custom InfoPlist string!",
          "microphoneUsagePermission": "$(PRODUCT_NAME) uses your microphone for AR experiences. This is a custom InfoPlist string!",
          "photosPermission": "$(PRODUCT_NAME) would like to read photos for AR experiences. This is a custom InfoPlist string!",
          "savephotosPermission": "$(PRODUCT_NAME) would like to save photos to your library during AR experiences. This is a custom InfoPlist string!"
        }
      }
    ]
  ],
}

Additional Requirements

As of v2.53.0, ReactVision ("reactvision") is the default provider for both Cloud Anchors and Geospatial Anchors. The ReactVision provider requires an rvApiKey and rvProjectId from ReactVision Studio — see ReactVision Studio Setup to generate these. If you need to use Google's ARCore provider instead, set provider to "arcore" in your plugin config (or on ViroARSceneNavigator) and provide a valid googleCloudApiKey. The old cloudAnchorProvider and geospatialAnchorProvider options are deprecated but still accepted as overrides.

Depending on what other packages you are using within your project, from version 2.50.1 onwards, you can also specify whether you want Cocoapods linking to be static or dynamic by adding iosLinkageto your plugin settings.

The iosLinkage, googleCloudApiKey, provider, rvApiKey, and rvProjectId are all optional values within your plugin. Since v2.53.0, provider defaults to "reactvision" — you only need to set it explicitly if you want to use "arcore" instead. When using the ReactVision provider, rvApiKey and rvProjectId are required for cloud and geospatial anchor functionality.


"@reactvision/react-viro",
{
  "android": {
    "xRMode": "AR"
  },
  "ios": {
    "cameraUsagePermission": "Your app uses your camera for AR experiences.",
    "microphoneUsagePermission": "Your app uses your microphone for AR experiences.",
    "photosPermission": "Your app would like to read photos for AR experiences.",
    "savephotosPermission": "Your app would like to save photos to your library during AR experiences."
  },
  "iosLinkage": "static",
  "googleCloudApiKey":"{you google cloud api key}",
  "provider": "reactvision",
  "rvApiKey": "YOUR_REACTVISION_API_KEY",
  "rvProjectId": "YOUR_REACTVISION_PROJECT_ID"
}

Run Prebuild

Run prebuild in order to create your native directories.

npx expo prebuild --clean

Running your Expo app

iOS

npx expo run:ios -d <device id | device name>

Android

npx expo run:android

Install Depth Model

If you would like to offer depth-based features, such as occlusion, to users with non-LiDAR iOS devices, then you'll also need to follow the instructions for installing the required depth model.

Install and Set Up Depth Model →


What’s Next