Skip to content

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-types and packages/api-client from 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-authentication and @react-native-google-signin/google-signin), reuses the TypeScript monorepo packages, and does not require native Swift/Kotlin skills.

Alternatives considered ​

OptionProsConsWhy not chosen
React Native + Expo managed (chosen)TypeScript; monorepo package reuse; EAS Build + Submit; native auth; strong communityRequires EAS Build (not Expo Go) for native modules; Expo managed config has limits— chosen
React Native bare workflowFull native control; no Expo managed limitsLoses EAS managed builds; requires more native tooling setupNo clear benefit at this stage; can eject later if needed
FlutterExcellent cross-platform performance; strong toolingDart (not TypeScript); cannot reuse packages/shared-types or api-clientMonorepo TypeScript reuse is a hard constraint
Native Swift + Kotlin (two codebases)Best native UX ceiling; full platform API access2× (or more) development effort; requires two separate skill setsImpractical at team size 1–3
Capacitor (web wrapper)Fastest to ship web → mobile; same codebase as webLimited native access; not truly native; push + offline are harderNative 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-authentication enables 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-signin natively, 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 ​

Heritage Community Hub — Internal. Access restricted via Cloudflare Access + Entra ID.