# React Native CodePush Alternative: The OTA Move

> By Lawrence Arya, Founder & CEO of VP0. Published 2026-06-07. 6 min read.
> Source: https://vp0.com/blogs/react-native-code-push-alternative

CodePush is archived and sunsetting. The replacement is not a drop-in; it is choosing an OTA strategy that fits your app.

**TL;DR.** The reason to seek a CodePush alternative is that CodePush is retired: Microsoft archived the repo and is sunsetting the App Center service. EAS Update is the natural successor for most teams (Expo's official OTA via expo-updates, for Expo and bare RN), with self-hosting the expo-updates protocol for those wanting control, and many code-push needs are actually remote-config toggles. OTA is JS-layer only: it ships bundle and asset fixes without App Store review but cannot change native code, which still needs a binary release. Ship it responsibly, staged rollouts, a fast rollback, restart etiquette, and keep two lanes straight: binary releases for native/major changes, OTA for JS fixes between them. A free VP0 design is the same starting point throughout.

## Why are you looking for a CodePush alternative?

Almost certainly because CodePush is going away. Microsoft's [CodePush](https://github.com/microsoft/react-native-code-push) (via App Center) was the go-to for over-the-air React Native updates for years, but it has been retired, the repo is archived, and App Center's CodePush service is being sunset, so every app that relied on it needs a new home for OTA updates. That is the real reason this search exists, and the honest answer is that the replacement is not a like-for-like drop-in; it is choosing a new OTA strategy that fits how your app is built.

The honest framing first: OTA updates let you ship **JavaScript-layer fixes without an App Store review**, and that is both their power and their boundary. They can update your JS bundle and assets; they cannot change native code, add a native module, or bump native dependencies, which still require a binary release. Any "CodePush alternative" that implies it can push native changes is misrepresenting what OTA is, and Apple's rules (updates must not materially change the app's purpose) bound what you should push regardless.

## What are the alternatives, and which fits?

The choice depends mostly on whether you are on Expo:

| Option | Best for | Note |
| --- | --- | --- |
| [EAS Update](https://docs.expo.dev/eas-update/introduction/) | Expo (and bare RN) apps | The natural successor; Expo's official OTA |
| Self-hosted (expo-updates protocol) | Teams wanting to own the server | More control, more to run |
| Re.Pack / module-federation approaches | Advanced, modular delivery | Heavier; for specific architectures |
| App-version-gated config | Simple toggles without code push | Not true OTA, but covers many needs |

For most teams, **EAS Update is the answer**: it is Expo's official OTA service, works with the expo-updates library that is already the modern standard, and handles the channel-and-rollout model CodePush users expect. A team that wants to own the infrastructure can self-host the expo-updates protocol. And a surprising number of "I need code push" needs are actually "I need to toggle a feature or fix a config remotely," which a remote-config approach solves without shipping new code at all, the same config-driven control as a [force-update gate](/blogs/force-update-app-store-popup-react-native/).

## What does shipping OTA responsibly require?

Restraint and honest update etiquette, because pushing code straight to users skips the review safety net. The disciplines: staged rollouts (release to a small percentage first, watch for crashes, then widen, never 100% blind), a kill switch or rollback (a bad OTA update must be revertable fast, the whole point of OTA cuts both ways), and respecting the user's session (do not force-restart mid-task to apply an update; apply on next launch or at a safe moment, the restart-etiquette every OTA build needs).

And the boundary must be honest: OTA is for JS-layer fixes and content, not for sneaking past App Review. [Apple's review guidelines](https://developer.apple.com/app-store/review/guidelines/) permit OTA updates that do not materially change the app, and an app that ships a fundamentally different experience via OTA is courting rejection, so the responsible use is bug fixes, copy changes, and incremental tweaks, with anything native or substantial going through a real release. This is the same don't-abuse-the-mechanism discipline as any [update or force-refresh flow](/blogs/expo-over-the-air-update-force-refresh-ui/).

## What completes the migration off CodePush?

The move and the model. Migrating means swapping the CodePush SDK for expo-updates / EAS Update (or your chosen path), re-creating your channels (production, staging) in the new system, and re-establishing the rollout process, with an agent handling the mechanical SDK swap and config. And keeping the mental model straight: a release pipeline now has two lanes, binary releases (App Store, for native and major changes) and OTA updates (for JS fixes between them), and knowing which lane a given change belongs in is the discipline that keeps OTA safe.

The screens are unaffected by the OTA mechanism, that is the point, so a free [VP0](https://vp0.com) design is the same starting point, and the update strategy is the delivery layer beneath, chosen to fit whether you are on Expo and how much infrastructure you want to own.

## Key takeaways: a CodePush alternative

- **CodePush is retired**: the repo is archived and App Center's service is sunsetting, which is why the search exists; plan a real migration.
- **EAS Update is the natural successor**: Expo's official OTA via expo-updates, for Expo and bare RN, with self-hosting for teams that want control.
- **OTA is JS-layer only**: it ships bundle and asset fixes without review; it cannot change native code, which still needs a binary release.
- **Ship OTA responsibly**: staged rollouts, a fast rollback/kill switch, and restart etiquette that does not interrupt the user mid-task.
- **Two lanes in the pipeline**: binary releases for native and major changes, OTA for JS fixes between them; know which lane each change belongs in.

## Frequently asked questions

**What is the best CodePush alternative for React Native?** EAS Update for most teams: it is Expo's official over-the-air service via the expo-updates library, works for Expo and bare React Native, and handles the channels and staged rollouts CodePush users expect. Teams wanting to own the server can self-host the expo-updates protocol, and many "code push" needs are actually remote-config toggles. A free VP0 design is the same starting point throughout.

**Why do I need a CodePush alternative?** Because CodePush is retired: Microsoft archived the repository and is sunsetting the App Center CodePush service, so apps relying on it must move to a new OTA solution. The replacement is not a like-for-like drop-in but a choice of OTA strategy, with EAS Update the natural successor for most React Native apps.

**Can OTA updates change native code?** No: over-the-air updates ship JavaScript-bundle and asset changes only, so they cannot change native code, add a native module, or bump native dependencies, all of which require a binary App Store release. Any alternative implying it can push native changes is misrepresenting what OTA is.

**How do I ship OTA updates responsibly?** With staged rollouts (release to a small percentage, watch for crashes, then widen), a fast rollback or kill switch for a bad update, and restart etiquette that applies updates on next launch or at a safe moment rather than interrupting the user mid-task. OTA skips the review safety net, so the rollout discipline replaces it.

**Is it allowed to update an app over the air on iOS?** Yes, within limits: Apple permits OTA updates that do not materially change the app's purpose, so bug fixes, copy changes, and incremental tweaks are fine, but shipping a fundamentally different experience via OTA courts rejection. Keep native and substantial changes in real binary releases and use OTA for JS-layer fixes between them.

## Frequently asked questions

### What is the best CodePush alternative for React Native?

EAS Update for most teams: it is Expo's official over-the-air service via the expo-updates library, works for Expo and bare React Native, and handles the channels and staged rollouts CodePush users expect. Teams wanting to own the server can self-host the expo-updates protocol, and many code-push needs are actually remote-config toggles. A free VP0 design is the same starting point throughout.

### Why do I need a CodePush alternative?

Because CodePush is retired: Microsoft archived the repository and is sunsetting the App Center CodePush service, so apps relying on it must move to a new OTA solution. The replacement is not a like-for-like drop-in but a choice of OTA strategy, with EAS Update the natural successor for most React Native apps.

### Can OTA updates change native code?

No: over-the-air updates ship JavaScript-bundle and asset changes only, so they cannot change native code, add a native module, or bump native dependencies, all of which require a binary App Store release. Any alternative implying it can push native changes is misrepresenting what OTA is.

### How do I ship OTA updates responsibly?

With staged rollouts (release to a small percentage, watch for crashes, then widen), a fast rollback or kill switch for a bad update, and restart etiquette that applies updates on next launch or at a safe moment rather than interrupting the user mid-task. OTA skips the review safety net, so the rollout discipline replaces it.

### Is it allowed to update an app over the air on iOS?

Yes, within limits: Apple permits OTA updates that do not materially change the app's purpose, so bug fixes, copy changes, and incremental tweaks are fine, but shipping a fundamentally different experience via OTA courts rejection. Keep native and substantial changes in real binary releases and use OTA for JS-layer fixes between them.

---
*Published on the [VP0 Journal](https://vp0.com/blogs). Free to read, index and cite with attribution.*
