Over-the-Air Updates
Over-the-Air (OTA) updates allow you to publish JavaScript, styling, and asset changes directly to users’ devices without rebuilding your app or going through app store review. This enables rapid bug fixes and feature deployments.How EAS Update Works
EAS Update publishes JavaScript bundles and assets to a CDN. When users open your app:- App checks for new updates on launch
- If available, downloads update in background
- Update applies on next app restart
- Users always get latest compatible version
- JavaScript code changes
- React components and logic
- Styles and layouts
- Assets (images, fonts, etc.)
- Configuration (app.json changes)
- Native code changes
- New native modules
- Expo SDK version upgrades
- App permissions changes
- Native configuration (AndroidManifest.xml, Info.plist)
Setting Up EAS Update
Configure Your Project
Run the configuration command:app.json
eas.json
Build with Update Support
Create a build that includes expo-updates:Publish Your First Update
Make changes to your JavaScript code, then publish:Update Channels and Branches
Channels
Channels link builds to update branches. Each build points to one channel. Common channel setup:eas.json
- Production builds →
productionchannel → receive production updates - Staging builds →
stagingchannel → receive staging updates - Each channel can have different update content
Branches
Branches are streams of updates published to channels. Publishing to branches:Runtime Versions
Runtime version determines update compatibility. Only updates with matching runtime version will be delivered. Runtime version policies:app.json
-
appVersion(Recommended):- Uses
versionfrom app.json - Example:
1.0.0→ runtime version1.0.0 - Update only delivered to apps with same version
- Clear, predictable versioning
- Uses
-
nativeVersion:- Uses native build numbers
- iOS: CFBundleShortVersionString + CFBundleVersion
- Android: versionName + versionCode
-
sdkVersion:- Uses Expo SDK version
- Example:
51.0.0 - Deprecated, not recommended
-
Custom string:
- Build app with
runtimeVersion: 1.0.0 - Publish updates for runtime version
1.0.0 - Only users with
1.0.0builds receive updates - When native code changes, increment to
1.1.0 - Build new app version with
1.1.0 - Publish separate updates for
1.1.0
Publishing Updates
Basic Update Publishing
Platform-Specific Updates
Automatic Updates from Git
Trigger updates on Git events using EAS Workflows:.eas/workflows/update-production.yml
Update Deployment Workflow
Recommended workflow for safe deployments:Advanced Update Features
Gradual Rollouts
Deploy updates to a percentage of users:- Start with 10% rollout
- Monitor crash reports and feedback
- Increase to 25%, 50%, 75%
- Complete with 100% rollout
Republishing Updates
Promote tested update from staging to production:Rolling Back Updates
Revert to previous working update:- Select channel to rollback
- Choose previous update to restore
- Confirm rollback
Update Groups
Manage related updates across channels:eas.json
Monitoring Updates
EAS Update Dashboard
View update analytics athttps://expo.dev/accounts/[account]/projects/[project]/updates:
- Total downloads: How many devices fetched update
- Successful updates: Updates applied successfully
- Failed updates: Update errors or rollbacks
- Platform breakdown: iOS vs Android adoption
- Version distribution: Which runtime versions are active
Update Logs
View update details:Runtime Metrics
Track update adoption in your app:Update Best Practices
Testing Before Release
- Test locally: Use Expo Go or development builds
- Preview channel: Share with internal team
- Staging channel: QA testing with staging builds
- Production rollout: Gradual deployment to users
Version Management
Align updates with builds:app.json
- Native code changes
- New native modules added
- Breaking changes in native configuration
- Expo SDK upgrade
- Bug fixes in JavaScript
- UI/UX improvements
- Feature toggles
- Analytics updates
- Non-native configuration changes
Update Messaging
Include meaningful messages:- What changed
- Why it changed (bug fix, feature, etc.)
- Ticket/issue reference
- Version or sprint number
Emergency Hotfixes
For critical production bugs:Update Size Optimization
Minimize update download size:-
Optimize assets:
- Compress images
- Use appropriate formats (WebP for images)
- Lazy load large assets
-
Code splitting:
- Use dynamic imports
- Defer non-critical code
-
Remove unused code:
- Tree shaking enabled by default
- Remove console.logs in production
- Minimize dependencies
Troubleshooting
Update Not Received
Issue: Users not getting published update Check:-
Runtime version mismatch:
-
Channel configuration:
eas.json
-
Update not published:
-
App not checking for updates:
- Ensure expo-updates is installed
- Check app.json configuration
- Verify build includes updates URL
Update Failed to Apply
Issue: Update downloaded but not applied Solutions:-
Check error logs:
-
Asset loading failure:
- Check asset URLs are accessible
- Verify CDN is reachable
- Check for CORS issues (web)
-
Corrupted update:
Wrong Runtime Version
Issue: Updates not compatible with builds Solution: Align runtime versions:app.json
Update Rollback Not Working
Issue: Rollback command fails or doesn’t revert Solutions:-
Manual rollback:
-
Create new update:
- Revert code changes in Git
- Publish as new update (faster than rollback)
Next Steps
- Build Configuration - Configure update channels in eas.json
- Internal Distribution - Test updates with beta testers
- Static Export - Deploy web version alongside native apps