Skip to content
useffect.sh
Book 30 min with a senior
Build & release

OTA update (EAS Update)

Shipping a new JavaScript bundle and its assets to installed apps without going through the stores; EAS Update is Expo’s service for it.

Definition

An OTA update (over-the-air) delivers a new JavaScript bundle and its assets (images, fonts) to an already installed React Native app, without publishing a new version on the App Store or Google Play. EAS Update is Expo’s hosted service that does this for apps embedding the expo-updates library. On launch, the app asks the server, downloads the manifest and any missing assets, and applies the update on the next launch; an update cannot change native code, permissions, or the SDK version. Three concepts drive targeting: the channel (fixed in the build through eas.json), the branch (the list of published updates), and the runtime version, which must match exactly between build and update. EAS Update replaces CodePush, whose hosted service (App Center) shut down on March 31, 2025. You meet it the first time a production bug has to be fixed faster than a store review.

In a real app

The production flow Expo recommends: eas update --channel staging on a test build, verification, then eas update:republish --destination-channel production to promote the exact same bundle, or eas update --channel production if environment variables differ. --rollout-percentage enables a gradual rollout, eas update:rollback returns to the previous update or to the one embedded in the binary. App-side behavior is set in app.json (updates.checkAutomatically, fallbackToCacheTimeout) and through the Updates API (checkForUpdateAsync, fetchUpdateAsync, reloadAsync) for teams that want to offer a reload instead of waiting for the next cold start.

Pitfall number one is the incompatible update: JavaScript calling a native module absent from the installed binary. The runtime version exists for that, and the fingerprint policy computes it from the actual native code. Number two: publishing an update from a dev machine with staging EXPO_PUBLIC_* variables. Number three: forgetting that the stores have rules; an update that changes app behavior beyond a fix is still subject to their terms.

In an audit I look at eas update:list --branch production, the channel-to-branch mapping (eas channel:list), and whether crashes carry an update identifier in the monitoring tool, otherwise nobody knows which code is actually running on users’ phones.

Our services on this

Sources

All 35 glossary terms

One of these is blocking your app?

30 minutes with a senior to look at the problem in your code. Free.