Today I tried to setup my EAS builds using multiple environments. When following these steps, the app config is not correctly setup due to undefined environment variables and I'm not sure what I'm doing wrong.
- Workflow:
managed - 'eas-cli' version:
eas-cli/15.0.12 darwin-arm64 node-v22.13.0
Steps I did:
- Created environment variables on Expo
- For my local development I've pulled them using the
eas env:pullcommand which created a .env.local with the correct values - In my app.config.ts I've made three different app variants based on the
APP_VARIANTenvironment variable, looking like this:
import { ConfigContext, ExpoConfig } from 'expo/config'
const colorGray200 = '#ECEDEE'
const colorGreenDefault = '#003D4F'
type TEnvironment = 'development' | 'preview' | 'production'
interface TAdaptiveIcon {
foregroundImage?: string
monochromeImage?: string
backgroundImage?: string
backgroundColor?: string
}
interface TSplashScreenConfig {
backgroundColor: string
image: string
dark?: {
image: string
backgroundColor: string
}
}
interface AppEnvironmentConfig {
name: string
identifier: string
icon: string
adaptiveIcon: TAdaptiveIcon
splash: TSplashScreenConfig
}
type AppConfig = Record<TEnvironment, AppEnvironmentConfig>
const appConfig: AppConfig = {
development: {
name: 'MyApp Dev',
identifier: 'app.myapp.be.dev',
icon: './assets/icon.png',
adaptiveIcon: {
foregroundImage: './assets/adaptive-icon.png',
backgroundColor: '#ffffff',
},
splash: {
backgroundColor: colorGray200,
image: './assets/splash-icon.png',
dark: {
image: './assets/splash-icon-dark.png',
backgroundColor: colorGreenDefault,
},
},
},
preview: {
name: 'MyApp Preview',
identifier: 'app.***.be.preview',
icon: './assets/icon.png',
adaptiveIcon: {
foregroundImage: './assets/adaptive-icon.png',
backgroundColor: '#ffffff',
},
splash: {
backgroundColor: colorGray200,
image: './assets/splash-icon.png',
dark: {
image: './assets/splash-icon-dark.png',
backgroundColor: colorGreenDefault,
},
},
},
production: {
name: 'MyApp',
identifier: 'app.***.be',
icon: './assets/icon.png',
adaptiveIcon: {
foregroundImage: './assets/adaptive-icon.png',
backgroundColor: '#ffffff',
},
splash: {
backgroundColor: colorGray200,
image: './assets/splash-icon.png',
dark: {
image: './assets/splash-icon-dark.png',
backgroundColor: colorGreenDefault,
},
},
},
}
export default ({ config }: ConfigContext): ExpoConfig => {
const appVariant: TEnvironment = process.env.APP_VARIANT
if (!appVariant) {
throw new Error(`APP_VARIANT environment variable not defined`)
}
const currentAppConfig = appConfig[appVariant]
return {
...config,
name: currentAppConfig.name,
slug: '****',
owner: '****',
version: '1.0.0',
scheme: currentAppConfig.identifier,
orientation: 'portrait',
icon: currentAppConfig.icon,
userInterfaceStyle: 'light',
newArchEnabled: true,
ios: {
icon: {
dark: './assets/images/ios-dark.png',
light: './assets/images/ios-light.png',
tinted: './assets/images/ios-tinted.png',
},
bundleIdentifier: currentAppConfig.identifier,
infoPlist: {
ITSAppUsesNonExemptEncryption: false,
},
},
android: {
adaptiveIcon: currentAppConfig.adaptiveIcon,
},
web: {
favicon: './assets/favicon.png',
},
plugins: [
'expo-router',
'expo-secure-store',
[
'expo-splash-screen',
{
...currentAppConfig.splash,
imageWidth: 200,
},
],
],
extra: {
router: {
origin: false,
},
eas: {
projectId: '0ffea***-****-****-****-**********8d',
},
},
}
}
- My eas.json looks like this
{
"build": {
"development": {
"env": {
"APP_VARIANT": "development"
},
"environment": "development",
"developmentClient": true,
"distribution": "internal"
},
"preview": {
"env": {
"APP_VARIANT": "preview"
},
"distribution": "internal",
"environment": "preview"
},
"production": {
"env": {
"APP_VARIANT": "production"
},
"environment": "production"
}
},
"cli": {
"appVersionSource": "remote"
}
}
- So now, every EAS command (build, env:pull, ..) I run, results into:
Failed to read the app config from the project using "npx expo config" command: npx expo config --json exited with non-zero code: 1.
Falling back to the version of "@expo/config" shipped with the EAS CLI.
- But running
npx expo configmyself, results in the printing of the development config.
What am I missing?
I also thought that adding the env APP_VARIANT in the eas.json is redundant due to the environments being available on EAS build servers.