Appearance
0002 — Mobile: React Native + Expo ​
Status: Accepted
Date: 2026-06-17
ADO work item: AB#3073
Deciders: Kristopher Turner (platform owner)
Context ​
The platform must deliver native iOS and Android apps sharing the same business logic and API contracts as the web app. The team is TypeScript-first and small (1–3 developers). The choice of mobile technology affects code reuse, developer skill requirements, release pipelines, and long-term maintenance cost.
Key constraints:
- Must support native Sign in with Apple (App Store requirement for apps offering third-party login) and Google Sign-In — requiring native builds, not Expo Go or browser-based OAuth.
- Must reuse
packages/shared-typesandpackages/api-clientfrom the monorepo. - Must support EAS Build for App Store + Play Store publishing (no macOS required for Android).
- Push notifications (APNs + FCM) and offline cache/sync are Phase 4 requirements.
Decision ​
We will use React Native + Expo (managed workflow) with EAS Build for both iOS and Android. This is the only cross-platform option that satisfies native Apple/Google sign-in (via
expo-apple-authenticationand@react-native-google-signin/google-signin), reuses the TypeScript monorepo packages, and does not require native Swift/Kotlin skills.
Alternatives considered ​
| Option | Pros | Cons | Why not chosen |
|---|---|---|---|
| React Native + Expo managed (chosen) | TypeScript; monorepo package reuse; EAS Build + Submit; native auth; strong community | Requires EAS Build (not Expo Go) for native modules; Expo managed config has limits | — chosen |
| React Native bare workflow | Full native control; no Expo managed limits | Loses EAS managed builds; requires more native tooling setup | No clear benefit at this stage; can eject later if needed |
| Flutter | Excellent cross-platform performance; strong tooling | Dart (not TypeScript); cannot reuse packages/shared-types or api-client | Monorepo TypeScript reuse is a hard constraint |
| Native Swift + Kotlin (two codebases) | Best native UX ceiling; full platform API access | 2× (or more) development effort; requires two separate skill sets | Impractical at team size 1–3 |
| Capacitor (web wrapper) | Fastest to ship web → mobile; same codebase as web | Limited native access; not truly native; push + offline are harder | Native auth and notifications require real native bindings |
Consequences ​
Positive ​
- One TypeScript codebase ships iOS and Android; reuses
packages/shared-types,api-client,shared-utils. - EAS Build handles iOS Archive + Android APK/AAB without macOS.
- EAS Submit automates App Store Connect + Google Play submission.
- Native
expo-apple-authenticationenables Sign in with Apple without browser redirects (required by ADR 0003 / Clerk Expo SDK). - Push notifications (APNs/FCM) and offline sync are well-supported in the Expo ecosystem.
Negative / trade-offs ​
- Expo Go cannot run native modules — all auth testing requires a dev build or EAS Build. Adds to the build feedback loop.
- Mobile has a separate release cadence from web (App Store + Play Store review, typically 1–3 days). Handled via a dedicated EAS pipeline, not a separate repo.
- Apple Developer account ($99/yr) is required for App Store publishing and Sign in with Apple — needed regardless of mobile framework.
Risks ​
- Android native Google Sign-In path — the exact native Google sign-in integration for Expo (whether Clerk's Expo SDK wraps
@react-native-google-signin/google-signinnatively, or whether a separate integration is needed) was not verified in the Phase-0 research pass. This must be confirmed before mobile scaffolding begins in Phase 4. - Expo managed workflow limits — some deep native customizations require ejecting to bare workflow. Mitigation: evaluate Expo's capability for each native feature before Phase 4; design the API to be UI-framework-agnostic.
References ​
- Platform strategy — mobile layer
- ADR 0003 — Authentication — Clerk Expo SDK native Apple sign-in (coupled)
- ADR 0001 — Monorepo —
apps/mobilelives in the monorepo - Clerk changelog: Native Sign in with Apple for Expo (Nov 2025)