Expo Application Services (EAS) Setup¶
This document covers the complete setup and usage of Expo Application Services (EAS) for building and deploying the Coaching App to iOS and Android app stores.
Overview¶
EAS Build and EAS Submit are cloud services that make it easier to build and submit your app to app stores without needing to configure complex build environments locally.
Key Features:
- Cloud-based builds (no need for macOS to build iOS apps)
- Build profiles for development, preview, and production
- Automatic code signing and provisioning
- OTA (Over-The-Air) updates with EAS Update
- Integration with App Store Connect and Google Play Console
Monorepo Configuration¶
This project uses Yarn workspaces. The following configuration ensures EAS Build works correctly:
.yarnrc.yml¶
This ensures packages are installed in proper node_modules directories that EAS Build can resolve.
.easignore¶
Located at frontend/.easignore, this controls what files EAS uploads:
# Include workspace root files
!../package.json
!../.yarnrc.yml
!../.yarn/**
# Include shared workspace package
!../shared/**
# Include parent node_modules for workspace hoisting
!../node_modules/**
# Exclude other workspaces
../backend/**
../docs/**
Metro Config¶
The metro config must extend @expo/metro-config (not expo/metro-config):
Prerequisites¶
Required Accounts¶
- Expo Account: Sign up at expo.dev
- Apple Developer Account: Required for iOS builds ($99/year)
- Google Play Developer Account: Required for Android builds ($25 one-time)
Local Setup¶
# Install dependencies
yarn install
# Login to Expo
yarn eas login
# Check EAS configuration
cd frontend && eas whoami
Configuration Files¶
eas.json¶
Located at frontend/eas.json, this file defines build profiles:
{
"build": {
"development": {
"developmentClient": true,
"distribution": "internal",
"ios": {
"simulator": true,
"bundleIdentifier": "pa.com.kaiju.coachingapp.dev"
},
"android": {
"buildType": "apk",
"package": "pa.com.kaiju.coachingapp.dev"
}
},
"preview": {
"distribution": "internal",
"ios": {
"simulator": false,
"bundleIdentifier": "pa.com.kaiju.coachingapp"
},
"android": { "buildType": "apk" }
},
"production": {
"distribution": "store",
"ios": {
"buildConfiguration": "Release",
"bundleIdentifier": "pa.com.kaiju.coachingapp"
},
"android": { "buildType": "app-bundle" }
}
}
}
Bundle Identifiers:
- Development:
pa.com.kaiju.coachingapp.dev- For local development builds - Preview/Staging:
pa.com.kaiju.coachingapp- For TestFlight/Internal Testing - Production:
pa.com.kaiju.coachingapp- For App Store release
app.json¶
The EAS project ID is configured in frontend/app.json:
Build Profiles¶
Development¶
For local development and internal testing:
yarn eas:build:dev # Both platforms
yarn eas:build:dev:ios # iOS only
yarn eas:build:dev:android # Android only
Features:
- Development client enabled
- iOS simulator builds
- Android APK (not AAB)
- Debug configuration
- Local API URL
Preview¶
For staging/QA testing before production:
yarn eas:build:preview # Both platforms
yarn eas:build:preview:ios # iOS only
yarn eas:build:preview:android # Android only
Features:
- Internal distribution (TestFlight/Internal Testing)
- Release configuration
- Staging API URL
- Device testing (not simulator)
Production¶
For app store release:
yarn eas:build:prod # Both platforms
yarn eas:build:prod:ios # iOS only
yarn eas:build:prod:android # Android only
Features:
- Store distribution
- Release configuration
- Production API URL
- Android App Bundle (AAB) for Play Store
- iOS IPA for App Store
iOS Setup¶
1. Apple Developer Account Configuration¶
Select "iOS" and follow prompts to:
- Set up Distribution Certificate
- Set up Provisioning Profile
- Configure Push Notification keys (if needed)
2. App Store Connect¶
- Create app in App Store Connect
- Update
eas.jsonwith your Apple details:
{
"submit": {
"production": {
"ios": {
"appleId": "your-email@example.com",
"ascAppId": "1234567890",
"appleTeamId": "ABCD123456"
}
}
}
}
3. Build and Submit¶
Android Setup¶
1. Generate Keystore¶
EAS can generate and manage your Android keystore automatically:
Select "Android" and follow prompts to generate a new keystore or upload existing one.
2. Google Play Console¶
- Create app in Google Play Console
- Create a service account for API access:
- Go to Setup → API access
- Create service account
- Download JSON key file
- Save as
frontend/google-play-service-account.json -
Add to
.gitignore -
Update
eas.jsonwith service account path:
{
"submit": {
"production": {
"android": {
"serviceAccountKeyPath": "./google-play-service-account.json",
"track": "production"
}
}
}
}
3. Build and Submit¶
Environment Variables¶
Environment variables are configured per build profile in eas.json:
{
"build": {
"production": {
"env": {
"APP_ENV": "production",
"API_URL": "https://coaching-app-backend.kaiju.com.pa"
}
}
}
}
Sensitive Secrets¶
Store sensitive values as EAS Secrets:
# Set a secret
eas secret:create --scope project --name API_KEY --value "your-secret-key"
# List secrets
eas secret:list
# Delete a secret
eas secret:delete --name API_KEY
Reference secrets in eas.json:
Over-The-Air (OTA) Updates¶
EAS Update allows you to push JavaScript updates without app store review:
1. Configure Updates¶
Updates are configured in app.json:
2. Publish Update¶
yarn eas:update
# Or specify branch
cd frontend && eas update --branch production --message "Fix critical bug"
3. Update Channels¶
Map build profiles to update branches in eas.json:
Common Workflows¶
First-Time Setup¶
# 1. Install dependencies
yarn install
# 2. Login to Expo
cd frontend
eas login
# 3. Configure credentials
eas credentials
# 4. Build development for iOS simulator
cd ..
yarn eas:build:dev:ios
Note: When prompted about custom metro config, select No to proceed. The config properly extends @expo/metro-config.
Release to Production¶
# 1. Update version in app.json
# 2. Test preview build
yarn eas:build:preview
# 3. Build production
yarn eas:build:prod
# 4. Submit to stores
yarn eas:submit:prod
Hotfix with OTA Update¶
Monitoring Builds¶
View Build Status¶
Build Dashboard¶
View all builds at: https://expo.dev/accounts/kaiju-labs/projects/coaching-app/builds
Troubleshooting¶
Build Failures¶
- Check build logs:
eas build:view [BUILD_ID] - Validate configuration:
cd frontend && eas config --type build - Clear EAS cache: Include
"cache": { "disabled": true }in build profile
Credentials Issues¶
# Reset iOS credentials
cd frontend
eas credentials -p ios
# Reset Android credentials
eas credentials -p android
Version Conflicts¶
Ensure all Expo packages are compatible:
Best Practices¶
1. Version Management¶
- Use semantic versioning (e.g.,
1.0.0) - Increment version in
app.jsonbefore each build - Use
appVersionSource: "remote"to sync with store versions
2. API Environments¶
- Development:
http://localhost:8055 - Preview/Staging:
https://staging-api.coaching-app.com - Production:
https://api.coaching-app.com
3. Testing¶
- Test preview builds on real devices before production
- Use internal distribution (TestFlight/Internal Testing) for QA
- Verify deep linking and push notifications
4. Security¶
- Never commit
google-play-service-account.json - Use EAS Secrets for API keys and sensitive data
- Rotate credentials periodically
- Review app permissions in
app.json
5. Build Optimization¶
- Use
app-bundlefor Android production (required by Play Store) - Enable Hermes for better performance
- Optimize images and assets
- Remove console logs in production
Resources¶
- EAS Build Documentation
- EAS Submit Documentation
- EAS Update Documentation
- Expo Documentation
- EAS Dashboard
Related Documentation¶
- Deployment Guide - Complete deployment process
- Development Workflow - Local development setup
- Security Best Practices - Security guidelines