React Native OTA Updates: Complete Guide (2026)
Over-the-air updates let you ship fixes and features to users instantly — no App Store review, no waiting. Here's everything you need to know about how they work, what's possible, and how to choose the right platform for your team.
What Are OTA Updates, and Why Do They Matter?
Over-the-air (OTA) updates — sometimes called hot updates or live updates — let you push new JavaScript code to your users without submitting a new binary to the App Store or Google Play. Your users get the update silently in the background, and the next time they open the app, they're running the new code.
The traditional mobile release cycle is brutal: write code, submit to review, wait 1–3 days, wait for users to update, iterate. A critical bug discovered on Monday might not reach all users until Thursday — and that's if review goes smoothly. OTA updates collapse that cycle from days to minutes.
For teams shipping features weekly or running A/B tests, the difference is qualitative, not just quantitative. OTA updates change what it's possible to iterate on — and how fast you can respond to production incidents.
How OTA Updates Work in React Native
React Native apps have two layers: the native shell (written in Swift/Objective-C for iOS, Kotlin/Java for Android) and the JavaScript bundle that contains your application logic, UI components, and business logic.
OTA updates work by replacing only the JavaScript layer. When your app launches, the native shell loads a JS bundle from the filesystem. By default, that bundle is the one bundled inside the app binary. An OTA SDK intercepts this load, checks a remote endpoint for newer bundle versions, downloads any update, saves it to local storage, and tells the native shell to load the updated bundle on the next launch (or immediately, depending on your config).
Here is what that lifecycle looks like in code with the RNPush SDK:
// App.tsx
import { withRNPush } from '@rnpush/client';
function App() {
return <RootNavigator />;
}
// Wrapping enables background update checks,
// crash detection, and auto-rollback.
export default withRNPush(App, {
channel: 'production',
crashThreshold: 3,
updateMode: 'on-next-launch',
});
The SDK handles the update check, download, verification, and rollback automatically. Your application code stays clean.
What You CAN and CANNOT Update OTA
The boundary is simple: anything that lives in the JavaScript bundle can be updated OTA. Anything that requires native compilation cannot. Getting this wrong is the most common source of broken updates — an OTA release that accidentally changes a native dependency causes crashes.
Can update OTA
- ✓React component changes
- ✓Business logic and state management
- ✓Styles, layouts, animations
- ✓Text and copy changes
- ✓Image and asset swaps (bundled assets)
- ✓Navigation configuration
- ✓API endpoints and feature flags
- ✓Third-party JS libraries
Cannot update OTA
- ✗New native modules or plugins
- ✗Permission declarations
- ✗App icon or launch screen
- ✗Push notification entitlements
- ✗Changes to Info.plist / AndroidManifest.xml
- ✗Native SDK upgrades (e.g. Firebase iOS SDK)
- ✗Minimum OS version requirements
- ✗App Store metadata
A good OTA platform will warn you — or block the release — when your update bundle references a native module version that doesn't match the installed binary. RNPush validates bundle compatibility against the native bridge hash before uploading.
Key Features to Look for in an OTA Platform
Binary diffing
Full bundle downloads are 5–15 MB. Binary diffing compares the new bundle against the last one and generates a patch — typically 50–200 KB. Faster downloads, less data for users on metered connections.
Auto-rollback on crash
If a bad update causes the app to crash repeatedly, the SDK should detect and automatically revert to the last stable bundle. Without this, a bad release stays broken until your team ships a fix and users download it.
Bring Your Own Storage (BYOS)
Bundles stored on the vendor's CDN mean your compiled code lives on servers you don't control. BYOS routes bundles through your own S3, GCP, or R2 bucket — giving you full data sovereignty and eliminating bandwidth mark-ups.
Staged rollouts and A/B testing
Push an update to 5% of users first, monitor crash rates, then ramp to 100%. A/B testing takes this further — you can push different UI variants to different cohorts without an App Store release.
Predictable pricing
Per-MAU and per-bandwidth billing compounds painfully as you scale. Look for flat-rate plans where your OTA bill doesn't spike every time you ship a feature or acquire new users.
Comparing OTA Platforms in 2026
With CodePush dead, the main options for React Native OTA updates are Expo EAS Update, Stallion, and RNPush. Here's how they compare on the dimensions that matter most.
| Feature | Expo EAS | Stallion | RNPush |
|---|---|---|---|
| Pricing model | MAU + bandwidth | Per-app flat | Flat-rate |
| BYOS | No | No | Yes — all plans |
| Binary diffing | Hermes only | Yes | All bundlers |
| Auto-rollback | No | Manual | Automatic |
| A/B testing | No | No | Yes — Growth+ |
| CodePush migration | Manual | Manual | Automated wizard |
See the full RNPush vs Expo EAS comparison for detailed pricing at each scale.
Getting Started with RNPush
RNPush is designed to be set up in a single session. The CLI handles project detection, storage connection, and your first bundle push. Here's the quickstart:
# 1. Install and initialise
npm install @rnpush/client
npx rnpush init
# 2. Push your first update
npx rnpush push --channel production
# 3. Check delivery stats
npx rnpush status --channel production
The free Hobby plan supports one app, three developers, and up to 50 updates per day — enough to ship OTA updates on a real production app without spending anything. No credit card required.
Start shipping OTA updates free
Binary diffing, auto-rollback, A/B testing, and BYOS — all in a flat-rate plan that doesn't penalise growth.
Join the waitlist →Free plan available · No credit card required