Skip to main content

mobile-expo-app

Why It Exists

This skill wasn't written speculatively — it was extracted after 6 of 13 sibling repos in a fleet rollout independently built the exact same shape: an apps/mobile Expo Router app in the same pnpm workspace as an existing Next.js+api pair, authenticating against the same Supabase project as the web app rather than standing up a separate identity system. It shipped in commit e3f255f, the same commit that hardened local-dev-stack and prod-deploy from that rollout's findings — all three skills came out of the same 13-repo pass.

The most concrete of its seven invariants — that EXPO_PUBLIC_* variables must exist at expo prebuild time, not bundle time — is a direct, provable failure mode rather than a stylistic preference: the React Native bundle-phase script's working directory sits inside node_modules/ react-native, so it never sees apps/mobile/.env.local directly. It's expo prebuild (which eas build runs internally) that actually bakes the extra block into the native binary, and if a variable is missing at that specific moment, it bakes in silently as an empty string — no error, just a build that looks fine until someone tries to use it.

What It Does

Stands up the mobile companion app: Expo Router wired into the same pnpm workspace, environment variables threaded through app.config.js and EXPO_PUBLIC_* correctly (with the prebuild-timing gotcha handled), a build-profile progression that starts free (eas build --profile preview, no paid Apple or Google account needed) before spending on production credentials, and a documented, honest accounting of what it takes to ship a complete push-notification pipeline versus what's needed for actual physical-device delivery.

How To Use It

Trigger phrases: "expo build", "eas build", "EXPO_PUBLIC_", "app.config.js prebuild", "expo push notifications", "TestFlight", "fastlane ios", "mobile companion app", or standing up apps/mobile in this pattern.

skills add git@github.com:catesandrew/next-starters.git --skill skills/mobile-expo-app -g
npm install @next-starters/skill-mobile-expo-app
/plugin marketplace add catesandrew/next-starters
/plugin install mobile-expo-app@next-starters

Gotchas & Invariants

  • EXPO_PUBLIC_SUPABASE_URL and the publishable key must be the identical values the web app uses — this is one shared Supabase backend, not a mobile-specific project. Session storage choice (AsyncStorage vs. expo-secure-store) is a deliberate per-repo decision based on actual session payload size against secure-store's roughly 2KB limit, not a universal default.
  • Start with eas build --profile preview and prove the whole pipeline works before spending on an Apple Developer ($99/yr) or Google Play ($25 one-time) account.
  • eas update (OTA) ships JS/style/EXPO_PUBLIC_* changes only — a native config change, icon, permission, or bundle-identifier change needs a fresh eas build, and OTA will silently no-op those instead of erroring.
  • Apple Store Connect app-record creation cannot be done through the ASC API at all — produce requires an interactive Apple-ID login, which is exactly why a local fastlane path (create_app, beta, release, deploy_device) exists alongside EAS.
  • A push-notification pipeline can be architecturally complete and working end-to-end in simulator/preview builds while physical-device delivery still needs an uploaded APNs .p8 key and Firebase FCM service-account JSON in Expo's credential store — that gap is common and explicitly not hidden, not a sign of a broken implementation.
  • Push-token registration must key to user.id, never to a JWT org claim — the org claim is unreliable for a multi-org user.
  • Never trust a plan document's stale "pending approval" status header over what's actually implemented and running on disk.
  • mobile-store-submission — the app-record, listing, and review side once a signed build from this skill's fastlane path exists.

Sourced from: skills/mobile-expo-app/metadata.json, skills/mobile-expo-app/SKILL.md, git commit e3f255f