hz-android-2d-porting
Guides porting existing Android 2D apps to Meta VR and Horizon OS — input adaptation, panel layout, and design requirements. Use…
Guides shipping a web app to the Meta VR and Horizon OS Store as a PWA/TWA — both 2D windowed panels and immersive WebXR/VR. Covers building the web app (IWSDK for WebXR, any responsive PWA for 2D), Vercel deploy, web app manifest + icons, the WebXR-only auto-enter-session step,
Claude Code
$ npx -y skills add meta-quest/agentic-tools --skill hz-store-pwa --agent claude-code
Codex
$ npx skills add meta-quest/agentic-tools --skill hz-store-pwa -a codex -y
Cursor
$ npx skills add meta-quest/agentic-tools --skill hz-store-pwa -a cursor -y
Gemini CLI
$ npx skills add meta-quest/agentic-tools --skill hz-store-pwa -a gemini-cli -y
GitHub Copilot
$ npx skills add meta-quest/agentic-tools --skill hz-store-pwa -a github-copilot -y
OpenCode
$ npx skills add meta-quest/agentic-tools --skill hz-store-pwa -a opencode -y
Windsurf
$ npx skills add meta-quest/agentic-tools --skill hz-store-pwa -a windsurf -y
name: hz-store-pwa license: Apache-2.0 description: Guides shipping a web app to the Meta VR and Horizon OS Store as a PWA/TWA — both 2D windowed panels and immersive WebXR/VR. Covers building the web app (IWSDK for WebXR, any responsive PWA for 2D), Vercel deploy, web app manifest + icons, the WebXR-only auto-enter-session step, choosing 2D vs immersive mode in @meta-quest/bubblewrap-cli, keystore/Digital-Asset-Links, and ovr-platform-util Store upload. Use before any IWSDK/WebXR build, PWA packaging, bubblewrap, or Horizon Store upload work. allowed-tools: Bash(npx:*), Bash(npm:*), Bash(curl:*), Bash(bubblewrap:*)
Guide the end-to-end process of wrapping a web app as a Meta VR app and shipping it to the Meta Horizon Store. This skill covers both delivery modes — a **2D windowed panel** and an **immersive WebXR/VR** experience — through the same pipeline: build the web app, deploy to Vercel, add a PWA manifest + icons, package as a signed Meta VR APK with `@meta-quest/bubblewrap-cli`, and upload with `ovr-platform-util`.
Commands use `<…>` tokens (e.g. `<DOMAIN>`, `<HORIZON_APP_ID>`, `<team-slug>`, `<PW>`) — substitute your own values before running.
Use this skill when you need to:
that won't launch, or an upload that's blocked
For deeper IWSDK app-building guidance, see the `hz-iwsdk-webxr` skill. For the broader Store submission process (VRC compliance, store assets, review tracking), see the `hz-store-submit` skill.
The full pipeline follows this order. The two mode-specific deltas are flagged; all other steps are identical for 2D and immersive.
0. Pick app mode → 2D panel vs immersive WebXR (sets steps 1 + 4) 1. Build the web app → IWSDK WebXR app (immersive) OR any responsive PWA (2D) 2. Deploy to Vercel → public HTTPS origin = <DOMAIN> 3. Manifest + icons → installable web app manifest, PNG icons, live on <DOMAIN> 4. Package as APK → bubblewrap: keystore, twa-manifest, build, asset links 5. Upload to the Store → ovr-platform-util upload-quest-build
Dependencies between steps matter — see [Order of Operations](#order-of-operations) at the end.
The app mode is the single most important decision, chosen once. It changes exactly two things downstream:
1. Whether the web app auto-enters a WebXR session on launch (immersive only). 2. The `horizonOSAppMode` value in `twa-manifest.json` (`"immersive"` vs `"2D"`).
| | **2D PWA** | **Immersive WebXR PWA** | |---|---|---| | Runs as | windowed 2D panel on Horizon | enters a full VR/WebXR session | | Web app | any responsive PWA (IWSDK optional) | WebXR app (IWSDK is the easy path) | | Auto-enter `requestSession` | **NO — do not add it** (Step 1) | **YES — built into the app** (Step 1) | | `horizonOSAppMode` | `"2D"` (Step 4) | `"immersive"` (Step 4) |
A wrong `horizonOSAppMode` value is the classic failure mode: a 2D app set to `immersive` is stuck loading; an immersive app set to `2D` shows a browser URL bar.
See [`references/app-modes.md`](references/app-modes.md) for the full decision guide.
Scaffold with `@iwsdk/create` (the only supported scaffolder):
npx @iwsdk/create@latest <app-name> --yes --mode vr --no-metaspatial \ --no-physics --no-locomotion --grabbing
Toggle `--physics` (Havok gravity/collisions), `--locomotion` (roam a large space), and `--grabbing` (hands/controllers pick objects up) to fit the app. For arcade-style apps prefer deterministic manual motion over physics.
**Don't reinvent IWSDK app code.** The template's bundled `CLAUDE.md`, `.claude/skills/iwsdk-*` skills, and the `iwsdk-rag` MCP are the source of truth for imports, ECS, XR input, physics, UI, and debugging. Query those rather than guessing.
**Build auto-enter into the immersive app from the start.** An installed immersive PWA opens with no 2D page, so the app itself must start the session on load (the app-icon tap is the user activation). Gate it on `getDigitalGoodsService` so it runs only in the installed PWA, never a browser tab:
const nav = navigator as Navigator & { xr?: { isSessionSupported?: (m:string)=>Promise<boolean> } };
if ("getDigitalGoodsService" in window && nav.xr?.isSessionSupported) {
nav.xr.isSessionSupported("immersive-vr")
.then(s => { if (s) world.launchXR(); }) // IWSDK launchXR == requestSession + setup
.catch(() => {});
}`getDigitalGoodsService` is device-only — validate this path on the headset.
Any responsive web app/PWA works — IWSDK is not required. It runs as a single- instance standalone panel with its own Library entry. Make sure it's a valid installable PWA (Step 3) and build/deploy it like any static/SPA site (Step 2). Do **NOT** add the auto-enter code above.
Full scaffolding flags, project layout, and the auto-enter rationale are in [`references/app-modes.md`](references/app-modes.md).
The web app must be live on a public HTTPS origin before packaging — `bubblewrap` fetches the manifest and icons from it. Set `base: "./"` in your Vite config, then:
npx -y vercel@latest whoami npx -y vercel@latest teams ls npx -y vercel@latest deploy --prod --yes --scope <team-slug>
Two URLs result:
Guides porting existing Android 2D apps to Meta VR and Horizon OS — input adaptation, panel layout, and design requirements. Use…
Upgrades Meta VR apps to newer Horizon OS SDK versions — migration guides, deprecated API replacements, changelog. Use when…
Guides design of comfortable, intuitive VR/MR experiences for Meta VR and Horizon OS — comfort guidelines, interaction patterns,…
Builds WebXR experiences for Meta VR and Horizon OS using the Immersive Web SDK (IWSDK) — ECS architecture, Three.js integration,…
Build multi-window Meta Horizon OS experiences with the MetaVrx Layout SDK in Jetpack Compose or React Native. Covers framework…
Builds app UI for Meta VR and Horizon OS with the MetaVrx UI Set, a Jetpack Compose component library and design system. Covers…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.