/expo-horizon
Software Mansion's guide for migrating Expo SDK apps to Meta Quest using expo-horizon packages. Use when adding Meta Quest or Meta Horizon OS support to an existing Expo or React Native project. Trigger on: Meta Quest, Horizon OS, Quest 2, Quest 3, Quest 3S, VR app,
$ npx -y skills add software-mansion-labs/skills --skill expo-horizon --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/expo-horizon
Context preview
The summary Claude sees to decide when to auto-load this skill.
Software Mansion's guide for migrating Expo SDK apps to Meta Quest using expo-horizon packages. Use when adding Meta Quest or Meta Horizon OS support to an existing Expo or React Native project. Trigger on: Meta Quest, Horizon OS, Quest 2, Quest 3, Quest 3S, VR app,
SKILL.md
expo-horizon.SKILL.mdname: expo-horizon
description: "Software Mansion's guide for migrating Expo SDK apps to Meta Quest using expo-horizon packages. Use when adding Meta Quest or Meta Horizon OS support to an existing Expo or React Native project. Trigger on: Meta Quest, Horizon OS, Quest 2, Quest 3, Quest 3S, VR app, expo-horizon-core, expo-horizon-location, expo-horizon-notifications, build flavors for Quest, panel sizing, VR headtracking, Horizon App ID, quest build variant, isHorizonDevice, isHorizonBuild, migrate expo-location to Quest, migrate expo-notifications to Quest, Meta Horizon Store publishing, or any task involving running an Expo app on Meta Quest hardware."
Expo Horizon: Migrating Expo SDK to Meta Quest
Software Mansion's production guide for adding Meta Quest support to Expo apps using the [expo-horizon](https://github.com/software-mansion-labs/expo-horizon) packages.
**This skill does not bundle a copy of the docs.** For any task below, always webfetch the linked official README or Meta documentation page to get up-to-date installation steps, plugin options, API surface, and feature matrices. This skill only captures the decision tree, critical rules, and non-obvious gotchas that agents routinely miss.
Decision Tree
What do you need to do?
│
├── Starting from scratch or adding Quest support to an existing Expo app?
│ └── Follow the "Setup Workflow" below (do NOT auto-install location or
│ notifications packages) and webfetch: expo-horizon-core README
│ ├── Install expo-horizon-core
│ ├── Configure the config plugin (horizonAppId, panel size, supportedDevices)
│ ├── Add quest/mobile build scripts
│ ├── Add runtime device detection (isHorizonDevice, isHorizonBuild)
│ └── Detect expo-location / expo-notifications, then ASK before migrating
│
├── Need location services on Quest?
│ └── Webfetch: expo-horizon-location README
│ ├── Replace expo-location with expo-horizon-location
│ ├── Review the feature support matrix
│ └── Guard unsupported calls (heading, geocoding, geofencing, background)
│
├── Need push notifications on Quest?
│ └── Webfetch: expo-horizon-notifications README
│ ├── Replace expo-notifications with expo-horizon-notifications
│ ├── Configure horizonAppId in expo-horizon-core
│ ├── Use getDevicePushTokenAsync (Expo Push Service is not supported)
│ └── Skip badge counts (not supported on Quest)
│
└── Need to build, run, or publish for Quest?
└── Webfetch: expo-horizon-core README (build variants) + Meta docs below
├── Build variants: questDebug, questRelease, mobileDebug, mobileRelease
├── Meta Quest Developer Hub (device management, sideloading)
└── Meta Horizon Store manifest requirementsSetup Workflow (adding Quest support to an existing Expo app)
Follow these steps **in order** when the user asks to add Meta Quest support. Do not combine steps 2 and 3 into a single install command — the sibling packages require explicit user confirmation.
1. **Install and configure `expo-horizon-core`.**
- Run `npx expo install expo-horizon-core`.
- **Ask the user for the config plugin values before writing them.** Present all options in a single prompt so the user can paste custom values or accept defaults in one pass. Show each option on its own line with its default in brackets, e.g.:
> I'll add the `expo-horizon-core` config plugin to `app.json`. Please confirm or override each value (press Enter / reply "default" to accept the bracketed default): > > - `supportedDevices` [`quest2|quest3|quest3s`] — pipe-separated Quest devices your app supports (**required** for Meta Horizon Store submission). > - `horizonAppId` [empty] — Meta Horizon application ID. Leave empty unless you plan to use push notifications; required by `expo-horizon-notifications` to issue device push tokens. > - `defaultWidth` [`1024dp`] — Default panel width. Leave blank to omit. > - `defaultHeight` [`640dp`] — Default panel height. Leave blank to omit. If you set width/height, make sure your Expo `orientation` matches (use `"landscape"` for wide panels). > - `disableVrHeadtracking` [`false`] — Set `true` to omit the `android.hardware.vr.headtracking` manifest entry. > - `allowBackup` [`false`] — Meta recommends `false` for sensitive data; set `true` only if you need Android backup in the Quest build.
- Only write the plugin config after the user replies. Omit any option the user left blank so the package's own default applies (don't write empty strings for `horizonAppId`, `defaultWidth`, or `defaultHeight`).
- Add `quest` / `mobile` build scripts to `package.json`.
- Run `npx expo prebuild --clean`.
- Webfetch the [expo-horizon-core README](https://github.com/software-mansion-labs/expo-horizon/blob/main/expo-horizon-core/README.md) for current option names and defaults before asking — the defaults above can change between releases.
2. **Detect existing location / notification packages. Do NOT install the horizon equivalents yet.**
- Read the project's `package.json`.
- Check `dependencies` and `devDependencies` for `expo-location` and `expo-notifications`.
- If neither is present, skip the rest of this workflow — the user has no migration to do.
3. **For each detected package, ask the user before migrating.**
- If `expo-location` is found, ask:
> "I found `expo-location` in your project. Do you want me to replace it with `expo-horizon-location` so location works on Meta Quest? (Quest has no GPS, heading, geocoding, or geofencing — unsupported calls will need to be guarded with `ExpoHorizon.isHorizonDevice`.)"
- If `expo-notifications` is found, ask:
> "I found `expo-notifications` in your project. Do you want me to replace it with `expo-horizon-notifications` so push notifications work on Meta Quest? This requires a `horizonAppId` in the core config plugin, uses Meta's push service (not the Exp
Read more
name: expo-horizon description: "Software Mansion's guide for migrating Expo SDK apps to Meta Quest using expo-horizon packages. Use when adding Meta Quest or Meta Horizon OS support to an existing Expo or React Native project. Trigger on: Meta Quest, Horizon OS, Quest 2, Quest 3, Quest 3S, VR app, expo-horizon-core, expo-horizon-location, expo-horizon-notifications, build flavors for Quest, panel sizing, VR headtracking, Horizon App ID, quest build variant, isHorizonDevice, isHorizonBuild, migrate expo-location to Quest, migrate expo-notifications to Quest, Meta Horizon Store publishing, or any task involving running an Expo app on Meta Quest hardware."
Expo Horizon: Migrating Expo SDK to Meta Quest
Software Mansion's production guide for adding Meta Quest support to Expo apps using the [expo-horizon](https://github.com/software-mansion-labs/expo-horizon) packages.
**This skill does not bundle a copy of the docs.** For any task below, always webfetch the linked official README or Meta documentation page to get up-to-date installation steps, plugin options, API surface, and feature matrices. This skill only captures the decision tree, critical rules, and non-obvious gotchas that agents routinely miss.
Decision Tree
What do you need to do?
│
├── Starting from scratch or adding Quest support to an existing Expo app?
│ └── Follow the "Setup Workflow" below (do NOT auto-install location or
│ notifications packages) and webfetch: expo-horizon-core README
│ ├── Install expo-horizon-core
│ ├── Configure the config plugin (horizonAppId, panel size, supportedDevices)
│ ├── Add quest/mobile build scripts
│ ├── Add runtime device detection (isHorizonDevice, isHorizonBuild)
│ └── Detect expo-location / expo-notifications, then ASK before migrating
│
├── Need location services on Quest?
│ └── Webfetch: expo-horizon-location README
│ ├── Replace expo-location with expo-horizon-location
│ ├── Review the feature support matrix
│ └── Guard unsupported calls (heading, geocoding, geofencing, background)
│
├── Need push notifications on Quest?
│ └── Webfetch: expo-horizon-notifications README
│ ├── Replace expo-notifications with expo-horizon-notifications
│ ├── Configure horizonAppId in expo-horizon-core
│ ├── Use getDevicePushTokenAsync (Expo Push Service is not supported)
│ └── Skip badge counts (not supported on Quest)
│
└── Need to build, run, or publish for Quest?
└── Webfetch: expo-horizon-core README (build variants) + Meta docs below
├── Build variants: questDebug, questRelease, mobileDebug, mobileRelease
├── Meta Quest Developer Hub (device management, sideloading)
└── Meta Horizon Store manifest requirementsSetup Workflow (adding Quest support to an existing Expo app)
Follow these steps **in order** when the user asks to add Meta Quest support. Do not combine steps 2 and 3 into a single install command — the sibling packages require explicit user confirmation.
1. **Install and configure `expo-horizon-core`.**
- Run `npx expo install expo-horizon-core`.
- **Ask the user for the config plugin values before writing them.** Present all options in a single prompt so the user can paste custom values or accept defaults in one pass. Show each option on its own line with its default in brackets, e.g.:
> I'll add the `expo-horizon-core` config plugin to `app.json`. Please confirm or override each value (press Enter / reply "default" to accept the bracketed default): > > - `supportedDevices` [`quest2|quest3|quest3s`] — pipe-separated Quest devices your app supports (**required** for Meta Horizon Store submission). > - `horizonAppId` [empty] — Meta Horizon application ID. Leave empty unless you plan to use push notifications; required by `expo-horizon-notifications` to issue device push tokens. > - `defaultWidth` [`1024dp`] — Default panel width. Leave blank to omit. > - `defaultHeight` [`640dp`] — Default panel height. Leave blank to omit. If you set width/height, make sure your Expo `orientation` matches (use `"landscape"` for wide panels). > - `disableVrHeadtracking` [`false`] — Set `true` to omit the `android.hardware.vr.headtracking` manifest entry. > - `allowBackup` [`false`] — Meta recommends `false` for sensitive data; set `true` only if you need Android backup in the Quest build.
- Only write the plugin config after the user replies. Omit any option the user left blank so the package's own default applies (don't write empty strings for `horizonAppId`, `defaultWidth`, or `defaultHeight`).
- Add `quest` / `mobile` build scripts to `package.json`.
- Run `npx expo prebuild --clean`.
- Webfetch the [expo-horizon-core README](https://github.com/software-mansion-labs/expo-horizon/blob/main/expo-horizon-core/README.md) for current option names and defaults before asking — the defaults above can change between releases.
2. **Detect existing location / notification packages. Do NOT install the horizon equivalents yet.**
- Read the project's `package.json`.
- Check `dependencies` and `devDependencies` for `expo-location` and `expo-notifications`.
- If neither is present, skip the rest of this workflow — the user has no migration to do.
3. **For each detected package, ask the user before migrating.**
- If `expo-location` is found, ask:
> "I found `expo-location` in your project. Do you want me to replace it with `expo-horizon-location` so location works on Meta Quest? (Quest has no GPS, heading, geocoding, or geofencing — unsupported calls will need to be guarded with `ExpoHorizon.isHorizonDevice`.)"
- If `expo-notifications` is found, ask:
> "I found `expo-notifications` in your project. Do you want me to replace it with `expo-horizon-notifications` so push notifications work on Meta Quest? This requires a `horizonAppId` in the core config plugin, uses Meta's push service (not the Exp
Software Mansion's set of skills for AI-assisted React Native development.
Repo: software-mansion-labs/skills
Other skills on software-mansion-labs-skills.
- /detour-onboarding
Complete onboarding guide for developers who are new to Detour, the open-source deferred deep linking SDK by Software Mansion. Use this skill whenever a user asks what Detour is, how to get started with Detour, how to set up deep linking with Detour, how to install the Detour
Open skill - /migrate-to-detour
Use when the user mentions migrating deep links, switching away from Branch or AppsFlyer, replacing their deep linking SDK, setting up Detour deep linking for the first time, or asks how Branch/AppsFlyer concepts map to Detour. Covers the complete migration end to end - Detour
Open skill - /fishjam
Software Mansion's Fishjam — hosted WebRTC platform for video, audio, and one-to-many livestreaming. MUST USE before writing, reviewing, or debugging ANY code that talks to a Fishjam instance from a backend (Node, Python) or a client (React web, React Native / Expo). Routes to
Open skill - /js-server-sdk
Node.js / TypeScript server SDK for Fishjam — backends that create rooms, mint peer tokens, listen to server notifications, and run agents. Use when writing a Node.js / Express / Fastify / Hono / NestJS backend that talks to Fishjam, sets up a webhook receiver, runs an AI agent,
Open skill - /platform
Fishjam platform fundamentals — domain model and auth shared by all SDKs. Covers glossary (room, peer, track, agent, streamer, viewer), the four room types (conference / audio_only / livestream / audio_only_livestream), two-tier auth (management vs peer tokens), Sandbox vs
Open skill - /python-server-sdk
Python server SDK for Fishjam — backends that create rooms, mint peer tokens, receive server notifications, and run voice agents. Use when writing a Python backend (FastAPI, Flask, Starlette, aiohttp) that talks to Fishjam, decorates a notification handler, decodes a Fishjam
Open skill

