Skip to content

Commit e49dedd

Browse files
committed
Merge remote-tracking branch 'upstream/main' into production
2 parents 87d7af4 + a03574d commit e49dedd

File tree

3 files changed

+251
-0
lines changed

3 files changed

+251
-0
lines changed
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
---
2+
title: 'React Native Comes to Meta Quest'
3+
authors: [lukaszchludzinski, janjaworski, markusleyendecker]
4+
tags: [announcement]
5+
date: 2026-02-24
6+
---
7+
8+
React Native has always focused on helping developers reuse knowledge across platforms. What started with Android and iOS has steadily expanded to Apple TV, Windows, macOS, and even the web with react-strict-dom. In 2021, the [Many Platform Vision post](/blog/2021/08/26/many-platform-vision) outlined a future where React Native could adapt to new devices and form factors without fragmenting the ecosystem.
9+
10+
At React Conf 2025, we took another step toward that vision by [announcing official React Native support for Meta Quest devices](https://youtu.be/NiYwlvXsBKw?si=IGl4MiF6QtywVFGL&t=1075). This post focuses on how to get started with React Native on Meta Quest, what works today, and how developers can build and ship VR apps using familiar tools and patterns.
11+
12+
<!--truncate-->
13+
14+
## Highlights
15+
16+
- [React Native on Meta Quest](#react-native-on-meta-quest)
17+
- [Getting started on Meta Quest](#getting-started-on-meta-quest)
18+
- [Development builds and native features](#development-builds-and-native-features)
19+
- [Platform-specific setup and differences from mobile](#platform-specific-setup-and-differences-from-mobile)
20+
- [Design and UX considerations for VR](#design-and-ux-considerations-for-vr)
21+
22+
## React Native on Meta Quest
23+
24+
<figure>
25+
<img src="/blog/assets/meta-quest-react-native.jpg" alt="React Native app running on Meta Quest headset" />
26+
<figcaption>
27+
React Native apps running on Meta Quest.
28+
</figcaption>
29+
</figure>
30+
31+
Meta Quest devices run Meta Horizon OS, an Android-based operating system. From a React Native perspective, this means all of the existing Android tooling, build systems, and debugging workflows work with minimal changes. For developers already building React Native apps on Android, much of existing development model carries over.
32+
33+
This aligns with how React Native has expanded to other Android-based environments over time. Rather than introducing a new runtime or development model, Meta Quest builds on the same Android foundation and integrates with React Native's existing abstractions. This allows platform-specific capabilities to be added without fragmenting the framework or requiring a separate approach to development.
34+
35+
## Getting started on Meta Quest
36+
37+
This section walks through the basic development workflow on Meta Quest, starting with Expo Go and moving toward development builds and platform-specific configuration.
38+
39+
### Step-by-step: Run an Expo app on Meta Quest
40+
41+
To run an Expo app on Meta Quest, start a standard Expo project, launch the dev server, and open the app through Expo Go on the headset. Beyond a few Meta Horizon OS-specific requirements, the workflow is the same as on Android.
42+
43+
1. **Install Expo Go on the headset**
44+
45+
[Expo Go is available on the Meta Horizon Store](https://www.meta.com/en-gb/experiences/expo-go/25322546364000780/) and can be installed directly on Meta Quest devices. It is used for rapid iteration during development.
46+
47+
2. **Create (or use) an Expo project**
48+
49+
If you're starting fresh, create a standard Expo app. No special template is required.
50+
51+
```sh
52+
npx create-expo-app@latest my-quest-app
53+
cd my-quest-app
54+
```
55+
56+
3. **Start the dev server**
57+
58+
```sh
59+
npx expo start
60+
```
61+
62+
4. **Connect with Quest using Expo Go**
63+
64+
Open Expo Go on the headset and scan the QR code displayed by the Expo CLI with the headset camera. The application launches in a new window on the device, allowing live reloading and fast iteration.
65+
66+
5. **Iterate as usual**
67+
68+
Code changes are reflected immediately on the device, following the same edit-refresh cycle used on Android and iOS.
69+
70+
## Development builds and native features
71+
72+
Expo Go is sufficient for early development and UI work. When access to native modules or deeper platform integration is required, development builds are used instead. These builds follow the standard Expo development build workflow and run directly on the Quest device.
73+
74+
## Platform-specific setup and differences from mobile
75+
76+
While the overall workflow remains the same, Meta Quest requires a small set of platform-specific adjustments.
77+
78+
### Project configuration for Meta Horizon OS
79+
80+
Meta Quest applications must meet specific requirements to run correctly and to be eligible for store submission. These include platform-specific Android configuration, product flavors, and application metadata.
81+
82+
Expo provides a plugin for Meta Horizon OS that applies these requirements at build time. Using this plugin ensures the project configuration aligns with Meta Quest expectations without manual modification of native files.
83+
84+
Install `expo-horizon-core` and add it to `app.json` or `app.config.js`:
85+
86+
```json
87+
{
88+
"expo": {
89+
"plugins": [
90+
[
91+
"expo-horizon-core",
92+
{
93+
"horizonAppId": "your-horizon-app-id",
94+
"defaultHeight": "640dp",
95+
"defaultWidth": "1024dp",
96+
"supportedDevices": "quest2|quest3|quest3s",
97+
"disableVrHeadtracking": false,
98+
"allowBackup": false
99+
}
100+
]
101+
]
102+
}
103+
}
104+
```
105+
106+
Also, change the orientation value:
107+
108+
```json
109+
{
110+
...
111+
"orientation": "default",
112+
...
113+
}
114+
```
115+
116+
Update `package.json` with Quest-specific scripts:
117+
118+
```json
119+
{
120+
"scripts": {
121+
"android": "expo run:android --variant mobileDebug",
122+
"quest": "expo run:android --variant questDebug",
123+
"android:release": "expo run:android --variant mobileRelease",
124+
"quest:release": "expo run:android --variant questRelease"
125+
}
126+
}
127+
```
128+
129+
### Using React Native without Expo
130+
131+
Expo provides the easiest way to get started with React Native on Meta Quest. If you prefer to build without a framework, you can also apply the required Meta Horizon OS configuration directly in your Android project.
132+
133+
At a minimum, this includes:
134+
135+
- Creating a Meta Quest-specific build flavor in `android/app/build.gradle`
136+
- Setting the `horizonAppId`
137+
- Defining a default panel size in the Android manifest
138+
- Declaring supported devices (for example: `quest2|quest3|quest3s`)
139+
- Removing prohibited permissions
140+
- Adjusting the minimum supported Android SDK version
141+
- Adding runtime checks such as `isHorizonDevice()` and `isHorizonBuild()`
142+
143+
To understand the full set of changes, you can inspect the `expo-horizon-core` plugin implementation and replicate the same configuration manually.
144+
145+
### Android without Google Play Services
146+
147+
Meta Horizon OS is built on Android Open Source Project (AOSP), which provides the core Android platform without Google's proprietary services. From a development perspective, this means applications run on standard Android APIs but do not have access to Google Mobile Services such as Play Services or Play Store–specific integrations.
148+
149+
When targeting Meta Quest, applications should be designed to avoid direct dependencies on Google services or to provide platform-specific alternatives where needed.
150+
151+
A list of unsupported dependencies is available in the [Meta Horizon OS documentation](https://developers.meta.com/horizon/documentation/android-apps/unsupported-dependencies).
152+
153+
### Permissions and device capabilities
154+
155+
Some Android permissions and hardware assumptions common on mobile devices do not apply to VR headsets. Cellular features (e.g. SMS), certain sensors (like GPS), and [restricted permissions](https://developers.meta.com/horizon/documentation/android-apps/unsupported-permissions/) are either unavailable or prohibited. Projects must explicitly account for these differences during setup.
156+
157+
### Evaluating library compatibility
158+
159+
Most React Native libraries work on Meta Quest, but compatibility depends on the assumptions a library makes about the underlying platform. In particular, libraries may rely on mobile-only hardware, touch input, or [services that are not available on Horizon OS](https://developers.meta.com/horizon/documentation/android-apps/unsupported-dependencies).
160+
161+
As a general guideline:
162+
163+
- Libraries that are self-contained and rely only on standard React Native and Android APIs typically work without changes.
164+
- Libraries that assume touch-only input, mobile-only hardware, or Google Mobile Services require adaptation or conditional usage.
165+
- Libraries that depend on restricted permissions or unavailable device capabilities are not supported.
166+
167+
For some common use cases, such as [location](https://github.com/software-mansion-labs/expo-horizon/blob/main/expo-horizon-location/README.md) and [notifications](https://github.com/software-mansion-labs/expo-horizon/blob/main/expo-horizon-notifications/README.md), Expo provides drop-in replacements for Meta Horizon OS. Other libraries may work as-is or require platform-specific handling depending on their dependencies.
168+
169+
### Platform-aware code paths
170+
171+
Applications targeting both Meta Quest and other platforms should guard platform-specific behavior. Meta Horizon OS provides runtime utilities to detect whether the app is running on a Quest device, allowing unsupported features to be disabled or replaced when necessary.
172+
173+
```js
174+
import ExpoHorizon from 'expo-horizon-core';
175+
176+
// Check if running on a Horizon device
177+
if (ExpoHorizon.isHorizonDevice) {
178+
console.log('Running on Meta Horizon OS!');
179+
}
180+
181+
// Check if this is a Horizon build
182+
if (ExpoHorizon.isHorizonBuild) {
183+
console.log('This is a Horizon build variant');
184+
}
185+
186+
// Access the Horizon App ID
187+
const appId = ExpoHorizon.horizonAppId;
188+
console.log('Horizon App ID:', appId ?? 'Not configured');
189+
```
190+
191+
## Design and UX considerations for VR
192+
193+
Designing for a head-mounted display introduces constraints that differ from touch-based mobile devices. Interfaces are viewed at a distance, rendered in space, and interacted with using a wider range of input methods.
194+
195+
UI elements generally require larger hit targets, increased spacing, and typography that remains readable across varying distances. These challenges are similar to those encountered on desktop, tablets, and foldable devices, where applications run in resizable windows and layouts must adapt dynamically.
196+
197+
One of the main differences between Meta Quest and Android mobile is input. Instead of relying primarily on touch, Meta Quest applications are commonly controlled through controllers, hand tracking, and optionally mouse and keyboard. Controllers behave more like a pointer device, which introduces interaction patterns that are closer to web and desktop UIs, including hover and focus-based navigation.
198+
199+
React Native's event system and component model can support these interaction patterns, but applications should avoid touch-only assumptions and ensure that UI elements provide clear focus states and predictable navigation when controlled through pointing devices.
200+
201+
Together, these considerations favor responsive layouts and input-agnostic interactions. React Native's layout system and component model provide a solid foundation for building comfortable and usable VR interfaces.
202+
203+
:::note
204+
205+
For more details, check out the [official design guidelines](https://developers.meta.com/horizon/documentation/android-apps/design-requirements).
206+
207+
:::
208+
209+
## Examples and references
210+
211+
### Reference project
212+
213+
- [Reference project with all the setup used in this article](https://github.com/callstackincubator/expo-meta-horizon-os-demo)
214+
- [Callstack Meta Horizon OS showcase app from React Conf](https://github.com/callstack/react-native-horizonos-example)
215+
216+
## Learn more
217+
218+
- [Official Meta Quest documentation](https://oss.callstack.com/react-native-meta-horizon-os/)
219+
- [React Native Developer's Guide to Meta Horizon OS (ebook)](https://www.callstack.com/ebooks/react-native-developers-guide-to-meta-horizon-os)
220+
- [How to Add Meta Quest Support to Your Expo Development Builds (article)](https://blog.swmansion.com/how-to-add-meta-quest-support-to-your-expo-app-68c52778b1fe)
221+
- [Bringing React Native to VR on Meta Quest (podcast)](https://www.callstack.com/podcasts/bringing-react-native-to-vr-on-meta-quest)
222+
- [React Native on Meta Quest: What We Learned About Building for VR (live stream)](https://www.youtube.com/watch?v=r-QL2EuqbdA)
223+
- [Getting started with Meta Horizon Development using Expo](https://www.youtube.com/watch?v=24G2tui0Ts8)
224+
- [Feedback channel for platform evolution](https://developers.meta.com/horizon/documentation/android-apps/bugs-requests)
225+
226+
## Acknowledgements
227+
228+
Bringing React Native to new platforms takes more than code. We're grateful to everyone who contributed their time, feedback, and support along the way.

website/blog/authors.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,3 +373,26 @@ alanleedev:
373373
socials:
374374
github: alanleedev
375375
image_url: https://github.com/alanleedev.png
376+
377+
lukaszchludzinski:
378+
name: Łukasz Chludziński
379+
title: Engineering Manager @ Callstack
380+
socials:
381+
x: lukasz_app
382+
github: lukasz-app
383+
image_url: https://github.com/lukasz-app.png
384+
385+
janjaworski:
386+
name: Jan Jaworski
387+
title: Software Engineer @ Callstack
388+
socials:
389+
x: jaworek3211
390+
github: jaworek
391+
image_url: https://github.com/jaworek.png
392+
393+
markusleyendecker:
394+
name: Markus Leyendecker
395+
title: Product Manager @ Meta
396+
socials:
397+
github: mliond
398+
image_url: https://github.com/mliond.png
246 KB
Loading

0 commit comments

Comments
 (0)