A leading product engineering company, creating adaptive software solutions to improve operations, providing businesses with expert development services from across domain.

A leading product engineering company, creating adaptive software solutions to improve operations, providing businesses with expert development services from across domain.

Mobile App Development

React Native OTA updates after CodePush was archived

CodePush has been read-only since May 2025 and the New Architecture changed the ground under it. How to choose React Native OTA updates in 2026.

React Native OTA updates after CodePush was archived

Microsoft archived react-native-code-push on 20 May 2025. The repository is read-only. There is no official replacement and no migration path.

What makes this awkward rather than simply annoying is that nothing breaks loudly. The package still installs. The integration steps still appear to work. Teams discover the state of React Native OTA updates when a release does not reach devices, which is the worst possible moment to start evaluating options.

What actually ended

Two separate things happened and they get conflated.

The first is that App Center was retired, taking the hosted CodePush service with it. Microsoft's guidance in the discussion thread on the archived repository pointed users toward a standalone version of CodePush that runs independently of App Center, available by contacting support. That is a self-hosting route, not a managed service.

The second is that the library itself stopped being maintained. Those are different problems: the first means you need somewhere to host, the second means nobody is fixing it as React Native moves.

And React Native has moved. Version 0.76 turned the New Architecture on by default. The post is careful about backward compatibility — it describes an automatic interoperability layer, states most apps will upgrade with the same effort as any other release, and notes the bridge remains for gradual migration.

It is equally careful about the limits. The interop layer has known limitations: it does not support accessing custom Shadow Nodes or concurrent features, and the post links a maintained list of them. An unmaintained native module sits precisely in the space those limitations describe, with nobody left to close the gap.

Why this is worse than an ordinary dependency going stale

An OTA update mechanism is the one part of your stack whose failure mode is silence.

If your networking library breaks, users see errors and you get crash reports. If your update mechanism breaks, the app carries on running the bundle it already has. Nobody reports anything. Your dashboard shows a successful release. The fix you shipped for a payment bug is sitting on a server, and you will find out from support tickets about a bug you believe you fixed a fortnight ago.

That asymmetry is why we treat this as a release-process question rather than a dependency-upgrade question.

What OTA is actually for

Before choosing a replacement it is worth being precise about the capability, because the four options differ mostly in how well they serve one of two very different uses.

The first is the emergency fix: something is broken in production, the fix is JavaScript-only, and waiting for store review is unacceptable. This is the case everyone cites to justify the pipeline. It is rare, high-stakes, and what matters is rollback speed and staged rollout.

The second is routine delivery: shipping ordinary changes weekly without the review cycle. This is what teams gradually start doing once the mechanism exists, and what makes the dependency load-bearing. What matters here is reliability and channel management, not speed.

Teams that use OTA for the first case and teams that use it for the second reach different conclusions from the same set of options, which is why generic comparison tables are unhelpful. Decide which you are before you read one.

The four paths, honestly

Stay on archived CodePush. Defensible only if you are pinned to an older React Native and have no plans to upgrade. You are accepting that the next React Native version you adopt may break OTA silently, and that no fix is coming. Put a date on when you will revisit, and treat any React Native upgrade as an event that requires end-to-end OTA testing on a real device.

Self-host the standalone server. Keeps the client integration you already have. You now operate an update server, which means uptime, storage, rollout controls and a rollback story are yours. Reasonable for a team that already runs infrastructure and has one or two apps. Poor value for a team that does not, because you are taking on operations to preserve an unmaintained client.

Move to a maintained service. Expo EAS Update is the most common destination and the one that tracks React Native releases. The cost is migration work and a dependency on someone else's pricing. For most teams shipping a product rather than maintaining a platform, this is the right answer, and the honest framing is that you were previously getting a hosted service for free and that arrangement ended.

Drop OTA entirely. Genuinely worth considering, and almost never considered. If you ship monthly, your store review turnaround is predictable, and you have never used OTA for an emergency fix, then the mechanism is complexity you maintain for a capability you do not use. Removing it is a legitimate outcome of this evaluation.

What the migration actually costs

The client swap is the small part. Budget for four things nobody scopes.

Release channel mapping. Whatever staging, beta and production channels you had need equivalents, and the semantics differ between providers. Getting this subtly wrong is how a staging bundle reaches production users, which is a worse outcome than having no OTA at all.

Version targeting rules. CodePush matched updates to binary versions with its own semantics. Every alternative does this differently. An update that targets the wrong binary range either reaches nobody, which you will not notice, or reaches an app whose native code cannot run it, which crashes on launch for everyone who received it.

Rollback drills. Not whether rollback exists, but whether someone on your team has done it once, on a weekday, with the runbook open. The first rollback should never be a real one.

The apps you forgot. Most teams with one React Native app have three: the product, an internal tool, and something built for a client two years ago that is still installed somewhere. The last of those is where the archived library will sit untouched for another year.

For a single app with a maintained upgrade path, this is a week. For a portfolio, it is a project, and it is worth treating as one rather than discovering it a repository at a time. Our mobile practice tends to run these as a single sweep across every app a client owns, because the second and third migrations cost far less than the first.

What to check before you choose

Three questions decide this faster than a feature comparison.

How often have you actually shipped an OTA update in the last year? Not how often you could have. Teams routinely maintain an update pipeline for an emergency that has never happened. If the answer is zero or one, the analysis is different.

What React Native version are you on, and when will you move? If you are pre-0.76 and staying there, you have more time than the archival date suggests. If you are upgrading, test OTA end to end on a physical device as part of that upgrade rather than after it.

Who owns a bad bundle at 11pm? Every OTA mechanism can ship a broken update to your entire install base in seconds — that is the same property that makes it useful. Rollback and staged rollout matter more than the update mechanism itself, and they are where hosted services earn their fee.

One constraint that overrides all of the above: both app stores place limits on what an over-the-air update may change. OTA is for JavaScript and assets. The moment a fix requires native code, a permission change or a new dependency with a native module, it is a store release regardless of which mechanism you chose. Teams that lean on OTA as the primary release channel eventually hit a fix that cannot ship that way, usually while treating it as an emergency.

The thing to do this week

Regardless of which path you pick, verify the current state rather than assuming it. Build a release, push an OTA update, and confirm on a physical device that the app picks it up. Not the simulator, and not a device that already has the bundle cached.

We build and maintain React Native apps, and this test is now part of every upgrade we do, because the failure is invisible from the console. Teams that run it discover the answer in an afternoon. Teams that skip it discover it during an incident.

If you are weighing the migration and want an outside read on which of the four paths fits, we are happy to look at it — including in the cases where the answer is that you should stop doing OTA.

Frequently asked questions

No. Microsoft archived the react-native-code-push repository on 20 May 2025, making it read-only. App Center was retired with it and there is no official replacement or migration path.

Treat it as unverified and test it yourself. React Native 0.76 enabled the New Architecture by default with an interop layer for legacy modules, but that layer has documented limitations and nobody is maintaining CodePush against them.

Four paths: stay on the archived library, self-host the standalone CodePush server Microsoft pointed users to, move to a maintained service such as Expo EAS Update, or drop OTA updates entirely.

Because the app keeps running the bundle it already has. There are no crashes and no error reports, and your release dashboard shows success. You find out from support tickets about a bug you believe you already fixed.

Build a release, push an update, and confirm a physical device picks it up — not a simulator, and not a device that already has the bundle cached. Run this as part of every React Native version upgrade.

Written by

Akash Mohapatra

Akash Mohapatra

Co Founder & Director

10 Sep 2026

·

8 min read

Share

LET'S CONNECT

Connect with Creuto!

Ready to take the first step towards unlocking opportunities, realizing goals, and embracing innovation? We're here and eager to connect.

Contact Us

We don't just aim to fit in – we strive to stand out. Experience the perfect blend of innovation, excellence, and trust that makes us truly unforgettable. Discover the difference with Creuto.

© 2026 Creuto All Rights Reserved