Managing Over-the-Air JS Updates with Expo EAS Update
Learn how to use EAS Update to deploy JavaScript and asset fixes to Expo apps without store reviews, using runtimeVersion and channels for safety.
14 Aug 2026, 23:18 UTC

Problem: Shipping urgent fixes without App Store delays
When a critical bug hits production, waiting for a full app store review cycle can take days. For apps using the Expo managed workflow, EAS Update allows you to ship JavaScript bundle and asset changes directly to installed users. The core technical challenge is ensuring that these updates are only delivered to binaries that can actually run them, preventing crashes caused by native module mismatches.
The solution relies on two concepts: the runtimeVersion and the Update Channel. The runtimeVersion acts as a compatibility guard; if the version in the update doesn't match the version baked into the native binary, the app ignores the update. The channel (e.g., production or staging) acts as a pointer to a specific update version, allowing you to promote a fix from testing to production without rebuilding the app.
Prerequisites
- An Expo SDK project configured for the managed workflow.
- The
expo-updateslibrary installed in the project. - An EAS account and the EAS CLI installed and authenticated on your local machine.
- A project linked to EAS via
eas.json.
Configuration Check
Verify your app.json or app.config.js contains the updates object. Without a defined runtimeVersion, the app may not correctly identify eligible updates.
// app.config.js
export default {
expo: {
name: "My App",
slug: "my-app",
runtimeVersion: {\n policy: "appVersion" // Ties runtime version to the native app version\n },
updates: {
url: "https://u.expo.dev/"
}
}
};
Note: Using policy: "appVersion" is a common strategy that ensures updates are only sent to users on the same version of the native binary.
Deployment Procedure
1. Generate the Native Binary
Before you can push updates, you must have a native binary distributed to users that is configured to check for updates. Run this command from your project root:
eas build --profile production --platform ios
Required Permissions: EAS account with build permissions for the project.
Risk: If you build a binary without the expo-updates configuration, that specific build will never receive over-the-air updates.
2. Publish the JavaScript Update
Once you have modified your JS code or assets, publish the bundle to a specific channel. This does not trigger a store submission.
eas update --channel staging --message "Fix: Corrected payment gateway logic"
Placeholders: Replace staging with your target channel name.
Expected Check: The CLI should return a unique updateId upon successful upload.
3. Client-Side Fetching
In the managed workflow, the app checks for updates by default on startup. To verify the update is being applied, you can monitor the app's startup logs or implement a version display in a hidden settings menu that reads the current update ID.
Verification and Diagnostics
To ensure the update reached the intended users, perform these checks:
- EAS Dashboard: Navigate to the "Updates" tab in the Expo dashboard. Confirm the
productionorstagingchannel is pointing to the most recentupdateId. - Runtime Match: If an update isn't appearing, compare the
runtimeVersionof the published update against theruntimeVersionof the installed binary. A mismatch will cause the client to silently ignore the update. - Network Inspection: Use a proxy tool to verify the app is making a request to the Expo update server on launch.
Recovery and Rollback
Because EAS Update uses channels as pointers, you can revert a breaking change without pushing new code.
Rolling Back to a Previous Version
If a published update causes crashes, use the EAS Dashboard to re-assign the channel pointer to a previous, stable updateId. This is an immediate change; the next time the app checks for updates, it will download the older, stable bundle.
Handling Native Incompatibility
If you accidentally push an update that requires a new native module (e.g., you added a library that requires pod install), the update will fail or crash for users. EAS Update cannot update native code.
Recovery:
- Roll back the channel to the last stable JS version.
- Increment the
runtimeVersionin your config. - Perform a full
eas buildand submit a new version to the App Store/Google Play.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.