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_URLand 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 (AsyncStoragevs.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 previewand 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 fresheas 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 —
producerequires 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
.p8key 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.
Related Skills
- 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