Configuration
Configure Expo environment keys, app variants, links, app config, and service fallbacks.
Expo configuration happens in two places:
.env.localor an environment-specific file provides public client keys.app.config.tsbuilds the native config, app identifiers, URL schemes, permissions, plugins, and EAS update metadata.
The config chain
Start from .env.example
cp .env.example .env.localUse .env.development, .env.preview, and .env.production when you want
separate values per build environment.
Expo inlines EXPO_PUBLIC_*
Every EXPO_PUBLIC_* value is bundled into the JavaScript that ships to users.
Treat these values as public: publishable Supabase anon keys, RevenueCat public
SDK keys, PostHog project keys, and Sentry DSNs are fine; service-role keys,
webhook secrets, APNs private keys, and Sentry auth tokens are not.
Providers read their own keys
Supabase is required for auth/data/storage. Optional providers check their keys: RevenueCat reports unconfigured, PostHog disables capture, Sentry disables SDK capture, update gates stay quiet, and links fall back to Expo-created URLs.
app.config.ts builds the native app config
The dynamic config derives display name, bundle/package ID, URL scheme, native permissions, plugins, associated domains, Android intent filters, EAS project ID, runtime version, and update URL.
Server-only values belong outside the JS bundle. Put
REVENUECAT_WEBHOOK_AUTH and APNs keys in Supabase Edge secrets; put
SENTRY_AUTH_TOKEN in EAS secrets or CI. Do not expose them as
EXPO_PUBLIC_*.
Starter .env.local
# Supabase
EXPO_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co
EXPO_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_PROJECT_ID=your-project-ref
# Optional providers
EXPO_PUBLIC_REVENUECAT_IOS_KEY=
EXPO_PUBLIC_REVENUECAT_ANDROID_KEY=
EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID=
EXPO_PUBLIC_GOOGLE_IOS_CLIENT_ID=
EXPO_PUBLIC_POSTHOG_API_KEY=
EXPO_PUBLIC_SENTRY_DSN=
APP_VARIANT=developmentRestart the Expo dev server after changing EXPO_PUBLIC_* values. Rebuild a
development client after changing native identifiers, plugins, permissions, or
URL scheme behavior.
Key reference
Supabase
Prop
Type
RevenueCat
Prop
Type
lib/purchases.tsx never configures RevenueCat on web. The app still reads
entitlement from Supabase through useEntitlement().isEntitled; RevenueCat
CustomerInfo is purchase/cache state, not the gate.
Google Sign-In
Prop
Type
Google Sign-In is native-only. The optional module is not loaded on web, and the button reports configuration errors when required IDs are missing.
PostHog
Prop
Type
Sentry
Prop
Type
Version gate
Prop
Type
Links, legal, and stores
Prop
Type
App variant
Prop
Type
App variants
app.config.ts derives identifiers from APP_VARIANT so development, preview,
and production builds can install side by side:
| Variant | App name | Bundle / package ID | URL scheme |
|---|---|---|---|
development | Soar Starter (Dev) | expo.soarstarter.com.dev | soar-starter-expo-dev |
preview | Soar Starter (Preview) | expo.soarstarter.com.preview | soar-starter-expo-preview |
production | Soar Starter | expo.soarstarter.com | soar-starter-expo |
The EAS profiles in eas.json set the same variant names:
developmentuses a development client, internal distribution, and thedevelopmentchannel.previewuses internal distribution, Android APK output, and thepreviewchannel.productionuses store distribution, auto-increments versions, and theproductionchannel.
Dynamic native config
Keep native app settings in app.config.ts, not in a static app.json. The
template currently configures:
newArchEnabled: trueand AndroidedgeToEdgeEnabled: true.- iOS and Android bundle identifiers from the active variant.
schemefrom the active variant.- iOS
associatedDomainsand AndroidintentFilterswhenEXPO_PUBLIC_LINKING_DOMAINis set. expo-router,expo-splash-screen,expo-apple-authentication,@react-native-google-signin/google-signin,expo-tracking-transparency, and Sentry plugins.- Camera, photos, notification, ATT, and Apple Sign-In permission/capability metadata.
- EAS project id,
runtimeVersion: { policy: "appVersion" }, and theexpo-updatesURL.
