Environment Configuration
The app supports three environments controlled by the APP_VARIANT environment variable.
Environments
| Environment | APP_VARIANT | API | Purpose |
|---|---|---|---|
| Development | development | Testing | Local dev with Expo dev server |
| Staging | staging | Testing | QA testing, PR builds |
| Production | production | Production | App Store releases |
For environment subtypes (e.g., E2E testing), use Updates.channel rather than creating additional APP_VARIANT values.
Key Files
env-config.json
Contains all environment variables. Generated from Doppler secrets:
npm run doppler:setup # first-time only — links the Doppler CLI to this repo's project/config
npm run generate-env-files:localWARNING
Never commit env-config.json - it contains sensitive secrets.
Doppler changes break OTAs
Doppler is the source of truth for all environment variables. Changing values in Doppler will change the app's runtime version, which breaks OTA update compatibility. Users on existing builds will not receive OTA updates until they install a new native build. Only modify Doppler values when releasing a new native build to the app stores.
src/env.ts
Centralized, type-safe access to all environment variables:
import env from 'src/env';
// Usage
env.API_URL; // Backend API endpoint
env.APP_VARIANT; // 'development' | 'staging' | 'production'
env.IS_PRODUCTION; // boolean
env.IS_DEVELOP_BUILD; // booleanRuntime Environment Detection
import env from 'src/env';
if (env.IS_PRODUCTION) {
// Production-only code
}
if (env.IS_DEVELOP_BUILD) {
// Development/staging code
}Best Practices
- Always use
src/env.ts- Never access Expo constants directly - Get added to the
engineer-appDoppler project first - A team lead needs to grant you access to theuat-zunoconfig beforenpm run doppler:setupwill work - Don't make production locally - Use github actions
- Use environment checks -
env.IS_PRODUCTIONfor conditional logic - Channel-based features - Use
Updates.channelfor feature flags