Mobile (overview)
The mobile clients are fully native: apps/ios-user + apps/android/app-user (customer) and apps/ios-agent + apps/android/app-agent (agent), built with Swift/SwiftUI and Kotlin/Compose. The earlier Expo apps (expo-user / expo-agent) and their React Native shared packages have been removed.
All mobile conventions — stack, the hand-written tRPC-over-HTTP client, cookie auth (not Bearer), generated design tokens, synced i18n, enum rules, Sentry, and per-platform build commands — live on the dedicated page:
➡️ Conventions → Mobile (Native iOS/Android)
Carried-over rules
Section titled “Carried-over rules”These hold across every mobile app regardless of platform:
- Cookie auth, never Bearer. Each app owns the
Cookie:header end-to-end and sends noOrigin(which is what exempts it from the server’s CSRF check). The backend (apps/api) is unchanged. - Generated design tokens, never hardcoded color. Read colors through the generated token layer (
@Environment(\.tokens)on iOS,LocalTokens.currenton Android) — never a raw hex /Colorliteral. - No hand-rolled buttons. Use each app’s shared
PrimaryButton/SecondaryButtonprimitives. - Read enums from
@repo/database.packages/database/src/enums.ts(values) andpackages/database/src/generated/db.ts(column types) are the source of truth —Tour.status = REQUESTED, notPENDING. There are no compile-time enum types on the wire, so a wrong literal fails silently at runtime. - Retained deep-link schemes. The native apps keep
expo-user://(customer) andexpo-agent://(agent) — Knock deep links depend on them. The names are historical; the apps are native. They are deliberately not in Better AuthtrustedOrigins: a trusted custom scheme, plus the since-removedexpo()plugin, made the auth server append the session cookie to a deep-link redirect.
See the native page for everything else.