Migration Guide · 2026

App Center is dead Migrate to AppsOnAir in under a day

Microsoft retired App Center on March 31, 2025. This is the complete playbook to move your React Native CodePush deployment to AppsOnAir: drop-in SDK, 1:1 CLI, zero workflow changes.

APPSONAIR
$ appsonair-codepush release-react MyApp ios \
    --deployment Production --rollout 25

Bundling app... Waiting
Size: 142 KB (Patch)

Ready to push
APPCENTER
$ appcenter codepush release-react MyApp ios \
    --deployment Production --rollout 25

Connecting... Error 410

Platform Retired
Global CDN Delivery
Patch Updates
$
RN 0.70+
S
BUILD
v2.4.1

DOWNLOADING BUNDLE

760

KB

Patch update · 7.2× smaller

Verified · SHA-256
Signature OK
Reload complete
Waiting for update...

Six things to know upfront

App Center retired March 31, 2025

Hosted CodePush stopped accepting new releases and serving updates the same day.

You don't rewrite anything

AppsOnAir is API-compatible with App Center CodePush. One import change in your App entry file.

CLI maps 1:1

appcenter codepushappsonair-codepush. Same flags, same arguments.

Most teams finish in under a day

The bulk is audit and validation; the actual code changes take an hour.

New Architecture works

AppsOnAir is tested across React Native 0.75 and above, including Bridgeless mode

You gain capabilities

Patch updates, SHA-256 signing, SOC 2 Type II (WIP), predictable pricing: all included.

The Deadline

The deadline already passed

Microsoft announced the retirement of Visual Studio App Center in mid-2024 with a hard cutoff of March 31, 2025. That date came and went. If you're reading this in 2026 and you still haven't migrated, your CodePush deployments aren't working, which probably explains why you're here.

Service Status

Visual Studio App Center

Microsoft Corporation

RETIRED

31 · MAR · 2025

  • Hosted CodePush no longer accepts releases
  • Existing deployments stopped serving updates
  • Build, distribute, analytics — all dark
  • Server source open-sourced before sunset

If you haven't migrated yet

You have four options.

1

Self-host the open-source CodePush Server

Maximum control, minimal cost, but you own the infrastructure, scaling, security, and 24/7 ops.

2

Move to Expo EAS Update

Solid platform, but requires adopting the Expo SDK and prebuild workflow. Significant rewrite for non-Expo projects.

3

Migrate to AppsOnAir CodePush

Recommended

Drop-in replacement, 1:1 CLI, ships with patch updates, SOC 2 compliance (WIP), and an integrated stack.

4

Plan for future platform changes

Choose a solution that actively supports evolving mobile frameworks, operating system updates, and new architecture requirements to minimise future migration efforts.

If your CodePush is silently broken
Some apps still work because users opened them before March 2025 and cached the last bundle. Anyone who installed fresh after that date is running stale code, and your dashboards probably won't show the issue clearly. Migration is overdue, not optional.
The Drop-In Promise

Why drop-in matters

Three things stay identical between App Center and AppsOnAir. That's why the migration is fast.

Same SDK API surface

sync(), checkForUpdate(), install modes, mandatory flags: the methods, parameters, and return types match what you wrote against App Center.

Same CLI command shape

release-react, promote, rollback, deployment ls. Every flag, every argument position, every output format your scripts depend on.

Same deployment-key model

Per-platform, per-environment keys. Production and Staging deployments out of the box. Promote releases between them. Your team's mental model carries over completely.

This was a deliberate design decision
When Microsoft announced App Center retirement, AppsOnAir built CodePush API-compatible on purpose, knowing thousands of teams had years of muscle memory and CI scripts depending on the exact CLI and SDK shape. Migration shouldn't be a re-architecture. It should be a swap.
The Mental Model

Three phases One workday

Before diving into the steps, here's the shape of the work. Most teams hit each phase in roughly the time shown below.

Map what you have

Inventory your current App Center setup. Deployment keys, target binary versions, custom SDK options, every CI script that calls the CLI.

Replace the moving parts

SDK package, CLI binary, deployment keys, CI/CD pipeline references. Keep your app's business logic untouched — only the OTA plumbing changes.

Canary and confirm

Ship a no-op release to 5% of users. Watch error rates and OTA telemetry for an hour. Roll forward to 100% if metrics are clean.

The Playbook

Six steps in order

Follow these in sequence. Skipping the audit and going straight to code-changes is how teams introduce avoidable production incidents during migration.

01
Inventory your current setup

Before you touch any code, document what's running. The audit usually surfaces things you forgot were there: old custom SDK options, update deployment keys in obscure scripts, target binary versions that no one's tracking.

Deployment keys

All Production and Staging keys, per platform.

Target binary versions

Versions currently in flight on the App Store and Play Store.

SDK config

Install mode, mandatory install mode, check frequency, custom UI overrides.

CI/CD references

Every workflow, script, or runbook that invokes the CLI.

02
Create your AppsOnAir workspace

Sign up at app.appsonair.com with your work email. Create a workspace, register your iOS and Android apps separately, then enable CodePush from each app's settings.

Create a workspace named after your team or company. Workspace names cannot be changed later.
Add your apps. Treat iOS and Android as separate apps even if they share a JS codebase because bundles are platform-specific.
Enable CodePush on each app. Production and Staging deployments are created automatically.
Copy each deployment key. You'll wire these into the SDK in step 3.
Invite your team and assign roles (Owner, Admin, Developer, Tester). Useful even before deployment.
03
Install the AppsOnAir SDK

Replace the App Center package with the AppsOnAir equivalent and update your import statements. Most apps need a single import change in App.tsx.

Terminal
# Remove the App Center package
$ npm uninstall react-native-code-push

# Install AppsOnAir CodePush SDK
$ npm install @code-push-next/react-native-code-push

# iOS only — install pods
$ cd ios && pod install && cd ..

Then update your app entry file. Note the import path is the only thing that changes: the API surface is identical.

App.tsx
// Before — App Center CodePush
import codePush from 'react-native-code-push';

// After — AppsOnAir CodePush
import codePush from 'code-push-next/react-native-code-push';

// Your existing config — unchanged
const codePushOptions = {
  checkFrequency: codePush.CheckFrequency.ON_APP_RESUME,
  installMode: codePush.InstallMode.ON_NEXT_RESTART,
  mandatoryInstallMode: codePush.InstallMode.IMMEDIATE,
};

export default codePush(codePushOptions)(App);
04
Replace the CLI

Install the AppsOnAir CLI globally and authenticate. The command surface mirrors App Center, so muscle memory carries over.

Terminal
# Install the AppsOnAir CLI globally
$ npm install -g @appsonair/codepush-cli

# Verify the install
$ appsonair-codepush --version
 1.x.x

# Authenticate (opens a browser to grant access)
$ appsonair-codepush login

# Confirm your apps are visible
$ appsonair-codepush app ls
 MyApp-iOS, MyApp-Android
05
Update your CI/CD pipelines

Find-and-replace appcenter codepush with appsonair-codepush across every workflow file. Argument shapes are identical.

.github/workflows/release.yml
name: OTA Release

on:
  push:
    branches: [main]

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm ci

      # Remove App Center steps
      - run: npm install -g appcenter-cli
      - run: appcenter login --token ${{ secrets.APPCENTER_TOKEN }}
      - run: appcenter codepush release-react -a MyOrg/MyApp-iOS \
          -d Production

      # Add AppsOnAir steps
      - run: npm install -g @appsonair/codepush-cli
      - run: appsonair-codepush release-react MyApp-iOS ios \
          --deployment Production 
        env:
          APPSONAIR_TOKEN: ${{ secrets.APPSONAIR_TOKEN }}
Migration complete. Your OTA update pipeline is now running on AppsOnAir.
The CLI Map

Every command
Side-by-side

This is the proof. Every App Center CodePush command has an exact AppsOnAir equivalent. Bookmark this and run a search-and-replace across your CI repo.

App Center CodePush
Purpose
AppsOnAir CodePush
appcenter login
Authenticate the CLI
appsonair-codepush login
appcenter apps list
List apps in your account
appsonair-codepush app ls
appcenter codepush deployment list -a Org/App
List deployments for an app
appsonair-codepush deployment ls <appName>
appcenter codepush release-react -a Org/App -d Production
Release a React Native bundle
appsonair-codepush release-react <appName>
appcenter codepush patch -a Org/App Production --rollout 100
Update rollout percentage
appsonair-codepush patch <appName>  --rollout 100
appcenter codepush rollback -a Org/App Production
Roll back the latest release
appsonair-codepush rollback <appName>
appcenter codepush deployment history -a Org/App Production
Inspect release history
appsonair-codepush deployment history <appName>
appcenter codepush release -a Org/App ./bundle 1.0.0 -d Production
Release a generic bundle
appsonair-codepush release <appName> ./bundle 1.0.0

Note the small structural shift: App Center used -a Org/App, AppsOnAir uses App as the first positional argument since workspaces handle org scoping.

A migration that respects your time

No retraining. No re-architecture. No new mental model. Just a swap.

<1 day
Typical Migration
1:1
CLI Mapping
No
Workflow Changes
The Gotchas

Four traps to avoid on day one

These are the issues that come up in real migrations, in roughly the order you'll hit them.

Update deployment keys

App Center keys baked into Info.plist or strings.xml are easy to miss.

Bridgeless reload silence

On RN 0.75 and above with the new architecture, the OTA installs, but the runtime doesn't reload silently.

Leftover CI references

Build scripts, runbooks, and Slack bot commands often reference the old CLI months after migration.

Stale binaries in stores

Users on a store binary that pre-dates the AppsOnAir SDK won't pick up new bundles.

What You Get

You don't just get parity you gain real capabilities

App Center CodePush stopped evolving years before it shut down. AppsOnAir picks up where it left off and adds what modern teams need.

1:1 CLI mapping

Every appcenter codepush command has a direct AppsOnAir equivalent. CI scripts get a find-and-replace, not a rewrite.

New Architecture native

Tested across React Native 0.75 and above, including Bridgeless mode. Documented restart patterns for bridgeless edge cases.

Patch updates included

Binary diffing on every release. Typical patches are 5–15% of the full bundle, cutting bandwidth by an order of magnitude vs full-bundle releases.

Compliance-grade

SOC 2 Type II (WIP) and ISO 27001:2022. SHA-256 bundle integrity verification. Audit-grade logging of every deployment, rollout, and rollback.

Predictable pricing

Flat tiers without per-update or per-bandwidth-GB charges. Free tier covers production validation. Your bill doesn't compound when your release cadence increases.

Unified workspace

AppsOnAir brings together AppSync, CodePush, OTA Distribution, AppLink, and AppRemark to help teams manage updates, distribution, deep linking, feedback, and app operations from one workspace.

The Time Cost

See how long alternatives actually take

Migration time is rarely the headline number, but it's the one that keeps engineering managers up at night. Here's the honest comparison from teams that have done each.

Migration Effort

Time from start to validated production

AppsOnAir CodePush ~1 day
Self-hosted CodePush Server 1–2 weeks
Expo EAS Update 3–5 days
Newer entrants (varies) 2–7 days

Why AppsOnAir Is Fastest

Three structural reasons

API compatibility was a design goal

Built specifically for App Center migrations. The API surface, install modes, and CLI shape were chosen to match.

No infra setup

Self-hosting the open-source CodePush Server requires you to provision, secure, and operate your own backend. Managed service eliminates that.

No framework lock-in

Unlike Expo EAS, you don't need to adopt a new build system. Your existing React Native project works as-is.

FAQ

Got Questions? We've Got Answers

When did Microsoft App Center CodePush retire?

How long does the migration to AppsOnAir CodePush take?

Do I need to rewrite my CodePush integration to use AppsOnAir?

Will my existing CodePush deployment keys work with AppsOnAir?

Can I run App Center CodePush and AppsOnAir CodePush in parallel during migration?

Does AppsOnAir support React Native New Architecture (Bridgeless mode)?

What does AppsOnAir CodePush cost compared to App Center?