React Native OTA updates#
A React Native app store binary contains two things: compiled native code and a JavaScript bundle plus its assets. An over-the-air (OTA) update replaces the JavaScript bundle and assets on a device that already has the binary installed. The app does not go through the App Store or Google Play again; it fetches the updated bundle in the background and runs it on the next launch.
This describes the general mechanism, independent of any specific OTA provider. The final section covers Rollbird's implementation of it.
What ships over the air#
The JavaScript bundle holds your application code: components, screens, navigation, and business logic, plus any pure-JavaScript dependency. Metro bundles static assets alongside it — images, fonts, and JSON files the app reads at runtime.
An OTA update swaps this bundle. The native shell stays exactly as installed: the compiled iOS and Android binary, the JavaScript engine (Hermes or JSC), and every native module already linked into it.
Examples of changes that ship over the air: a bug fix in a screen's logic, a new flow built from native modules already in the binary, a copy or styling change, an API endpoint change, a new pure-JavaScript dependency.
What still needs a store submission#
Anything that changes the compiled binary needs a new build and a new store submission. That includes:
- Adding or upgrading a dependency that ships native iOS or Android code, not only JavaScript.
- Upgrading React Native itself.
- Changing native configuration — an
Info.plistentry, anAndroidManifest.xmlpermission, a native build setting. - Changing the app's minimum OS version or target SDK.
A native-affecting change usually alters what the installed binary is capable of running, even when no application code changes. An OTA system that checks native compatibility before offering an update will not hand that update to a binary it no longer matches. That check is what keeps a JavaScript bundle built against one native surface from loading into a binary that does not have it.
Channels and staged rollout#
A channel is a named target for updates, embedded in the binary at build time. A common setup uses one channel for internal or preview builds and another for the build distributed to end users. Publishing to one channel does not reach binaries built for another — only a binary carrying that channel requests it.
Staged rollout limits a new update to a percentage of eligible devices instead of all of them at once. Publishing at a low percentage first, then watching crash and error rates before raising it, catches a bad release before it reaches your full install base.
Rollback#
Rollback reverts a channel to its previous working release without publishing a new one and without a store review. Because the update itself is a JavaScript bundle rather than a new binary, undoing it is a change to which release a channel serves, not a new build.
A rollback targets a release that is already live and already causing a problem, not one still being decided. Because the problem already exists in production, rollback needs to operate independently of the limits that gate a new release — a quota, a storage cap, a billing status.
How Rollbird does it#
Rollbird is a hosted OTA update service for React Native and Expo apps. rollbird init --channel preview links a project, provisions a signing key, and embeds a channel into your native build. rollbird release bundles, signs, and publishes your JavaScript bundle to that channel. rollbird rollback reverts a channel to its previous release — instantly, at no cost, and regardless of plan or quota.
The getting-started guide walks through the full path, from installation to a verified preview update and a tested rollback. The React Native SDK guide covers the wrapper, channels, compatibility strategies, and Expo configuration in more depth.
Rollbird's plans scale with apps, storage, seats, and release history, never with end users or monthly active users. See pricing for current plans.