All posts
3 min readBy BetterCodePush

Migrating from Microsoft CodePush to BetterCodePush

Microsoft App Center CodePush has been retired. Here is a practical, step-by-step path to move your React Native over-the-air updates to BetterCodePush without a risky big-bang cutover.

MigrationCodePushReact NativeOTA

Microsoft retired App Center on March 31, 2025, and with it the hosted CodePush service. The client SDK,react-native-code-push, was archived read-only shortly after, so no fixes are coming. If your React Native app still ships JavaScript updates through CodePush, you need a new home for that release pipeline. This guide walks through moving to BetterCodePush with as little risk as possible — no forced rewrite, no big-bang cutover.

What actually changes

CodePush and BetterCodePush solve the same problem — deliver a new JavaScript bundle to an already-installed native binary — so the mental model carries over. What changes is the delivery path: BetterCodePush owns the native bundle-loading path and serves updates from a public CDN, while your release credentials stay with your CLI and CI, never inside the app. One consequence worth knowing up front: because the bundle-loading path changes, the cutover requires exactly one new native build through the stores. After that, compatible JavaScript fixes can ship over the air; native-code, configuration, and runtime changes still require a new store build.

Prerequisites

  • A bare React Native project, or an Expo project using prebuild/CNG (SDK 52+).
  • Access to your app's native projects (you will ship one new native build).
  • A BetterCodePush organization and a Live API key from the console.

Step 1 — Install the CLI alongside CodePush

You do not have to remove CodePush first. Add the BetterCodePush CLI as a dev dependency so both can coexist while you validate the new path.

npm install --save-dev @bettercodepush/cli

Step 2 — Wire the native integration

The initializer installs the correct build integration and writes your platform app IDs into the native projects. Run it, then rebuild once.

npx bettercodepush init --build bare
npx pod-install # iOS

Step 3 — Ship one native build

Because the bundle-loading path changes, the cutover requires exactly one new native release through the App Store and Play Store. Once that build is live, compatible JavaScript fixes can ship over the air. Changes to native code, app configuration, or the JavaScript runtime still go through the stores.

Step 4 — Deploy your first OTA update

npx bettercodepush doctor
npx bettercodepush deploy --platform ios --target-app-version 1.0.0 --channel production

Start the rollout at a small percentage of devices, confirm the active release looks healthy, then expand. If anything looks wrong, disable the rollout — subsequent update checks fall back without deleting release history. There is a full playbook for this in staged rollouts and instant rollbacks.

Step 5 — Retire CodePush

Keep CodePush in place for the old binaries until they have aged out of your active user base. Then plan a later native store build that removes the CodePush SDK and its native integration; that cleanup cannot be delivered as an OTA update.

Rollouts and rollbacks, mapped from CodePush

If you relied on CodePush staged rollouts and rollbacks, the equivalents are direct: deploy to a device percentage, inspect the active release, and expand or disable it. Rollbacks affect the next update check rather than deleting history, so you keep a full audit trail of what shipped.

Next steps

Create an organization, generate a Live API key, and run bettercodepush doctor against a staging channel before touching production. The beta requires no billing setup, so you can validate the full pipeline end to end at no cost.

Ship your first update

Create an organization and deploy an over-the-air update in minutes. No billing setup during the beta.

Start with BetterCodePush