| name | expo-environments |
| description | Configure multi-environment setup for Expo apps with EAS Build. Trigger: When setting up dev/staging/production environments, configuring environment variables, or creating EAS build profiles.
|
| license | Apache-2.0 |
| metadata | {"author":"333-333-333","version":"1.0","scope":["root"],"auto_invoke":["Setting up Expo multi-environment configuration","Configuring EAS Build profiles","Managing environment variables in Expo/React Native"]} |
When to Use
- Setting up a new Expo project with multiple environments
- Configuring environment variables for dev, staging, production
- Creating EAS Build profiles for different environments
- Need different app identifiers/names per environment
- Managing API URLs, feature flags, or service keys per environment
Critical Patterns
1. Environment Variable Naming
All client-accessible variables MUST use EXPO_PUBLIC_ prefix:
EXPO_PUBLIC_API_URL=https://api.example.com
EXPO_PUBLIC_FIREBASE_API_KEY=xxx
API_URL=https://api.example.com
2. File Structure
project/
├── app.config.ts # Dynamic config (NOT app.json)
├── eas.json # EAS Build profiles
├── .env # Local development (gitignored)
├── .env.example # Template for team
└── src/
└── config/
└── env.ts # Type-safe env access
3. Three-Environment Setup
| Environment | Purpose | Distribution | App Suffix |
|---|
development | Local dev with dev client | simulator/internal | .dev |
staging | QA/testing builds | internal | .staging |
production | Store releases | store | (none) |
Configuration Files
eas.json
{
"cli": {
"version": ">= 5.0.0"
},
"build": {
"base": {
"node": "20.0.0",
"env": {
"APP_ENV": "development"
}
},
"development": {
"extends": "base",
"developmentClient": true,
"distribution": "internal",
"env": {
"APP_ENV": "development",
"EXPO_PUBLIC_API_URL": "http://localhost:3000/api"
},
"android"
app.config.ts
import { ExpoConfig, ConfigContext } from 'expo/config';
const APP_ENV = process.env.APP_ENV ?? 'development';
const envConfig = {
development: {
name: 'MyApp (Dev)',
bundleIdentifier: 'com.company.myapp.dev',
packageName: 'com.company.myapp.dev',
icon: './assets/icon-dev.png',
},
staging: {
name: 'MyApp (Staging)',
bundleIdentifier: 'com.company.myapp.staging',
packageName: 'com.company.myapp.staging',
icon: './assets/icon-staging.png',
},
production: {
name: 'MyApp',
bundleIdentifier: 'com.company.myapp',
packageName: 'com.company.myapp',
icon: './assets/icon.png',
},
} as const;
type AppEnv = keyof typeof envConfig;
const config = envConfig[APP_ENV as AppEnv] ?? envConfig.development;
({ : expoConfig }: ): ({
...expoConfig,
: config.,
: ,
: ,
: ,
: config.,
: ,
: ,
: {
: ,
: ,
: ,
},
: {
: ,
: config.,
},
: {
: {
: ,
: ,
},
: config.,
},
: {
: ,
: {
: ,
},
},
: [],
});
src/config/env.ts
type Environment = 'development' | 'staging' | 'production';
interface EnvConfig {
APP_ENV: Environment;
API_URL: string;
FIREBASE_API_KEY?: string;
SENTRY_DSN?: string;
}
function getEnvVar(key: string): string {
const value = process.env[key];
if (value === undefined) {
console.warn(`Environment variable ${key} is not defined`);
return '';
}
return value;
}
function getRequiredEnvVar(key: string): string {
const value = process.env[key];
if (value === undefined) {
throw new Error(`Required environment variable ${key} is not defined`);
}
return value;
}
export : = {
: (process.. ) ?? ,
: (),
: (),
: (),
};
isDev = env. === ;
isStaging = env. === ;
isProd = env. === ;
.env.example
APP_ENV=development
EXPO_PUBLIC_API_URL=http://localhost:3000/api
EXPO_PUBLIC_FIREBASE_API_KEY=
EXPO_PUBLIC_FIREBASE_AUTH_DOMAIN=
EXPO_PUBLIC_FIREBASE_PROJECT_ID=
EXPO_PUBLIC_SENTRY_DSN=
EXPO_PUBLIC_ENABLE_ANALYTICS=false
EXPO_PUBLIC_ENABLE_PUSH_NOTIFICATIONS=false
Commands
npx expo start
eas env:pull --environment development
eas build --profile development --platform all
eas build --profile staging --platform all
eas build --profile production --platform all
eas build --profile staging --platform android
eas build --profile staging --platform ios
eas submit --profile production --platform all
eas config --profile staging
eas build:list
Sensitive Variables (EAS Secrets)
For API keys and secrets that should NOT be in version control:
eas secret:create --name EXPO_PUBLIC_FIREBASE_API_KEY --value "your-key" --scope project
eas secret:list
eas secret:delete EXPO_PUBLIC_FIREBASE_API_KEY
Secrets set via eas secret:create override values in eas.json.
Checklist for New Project
Resources
- Templates: See assets/ for starter configs