Skip to content

Environment Configuration

The app supports three environments controlled by the APP_VARIANT environment variable.

Environments

EnvironmentAPP_VARIANTAPIPurpose
DevelopmentdevelopmentTestingLocal dev with Expo dev server
StagingstagingTestingQA testing, PR builds
ProductionproductionProductionApp 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:

bash
npm run doppler:setup   # first-time only — links the Doppler CLI to this repo's project/config
npm run generate-env-files:local

WARNING

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:

typescript
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; // boolean

Runtime Environment Detection

typescript
import env from 'src/env';

if (env.IS_PRODUCTION) {
  // Production-only code
}

if (env.IS_DEVELOP_BUILD) {
  // Development/staging code
}

Best Practices

  1. Always use src/env.ts - Never access Expo constants directly
  2. Get added to the engineer-app Doppler project first - A team lead needs to grant you access to the uat-zuno config before npm run doppler:setup will work
  3. Don't make production locally - Use github actions
  4. Use environment checks - env.IS_PRODUCTION for conditional logic
  5. Channel-based features - Use Updates.channel for feature flags