Migrating from AppCenter CodePush to Turbopush: The Complete Guide for React Native
If you're reading this, you're likely one of the thousands of developers affected by Microsoft's decision to shut down AppCenter CodePush on March 31, 2025. Don't panic—migrating to Turbopush is straightforward, and you can complete it in under 30 minutes.
The good news? Turbopush is 100% CodePush compatible. Your existing JavaScript code using the CodePush SDK requires minimal changes, and your deployment workflow stays virtually the same.
This guide will walk you through migrating your React Native app from AppCenter CodePush to Turbopush, step by step.
Why Migrate to Turbopush?
Before we dive into the technical steps, let's address the elephant in the room: why Turbopush instead of self-hosting?
When AppCenter announced its shutdown, many teams considered self-hosting alternatives like code-push-server or building their own infrastructure. Here's why that's often not the best choice:
Turbopush vs Self-Hosted: A Comparison
| Feature | Turbopush | Self-Hosted |
|---|---|---|
| Setup Time | ~10 minutes | Days to weeks |
| Infrastructure Management | Zero—we handle it | You're responsible for servers, databases, storage |
| Global CDN | ✅ Built-in, worldwide | ❌ You need to configure and pay for CDN |
| Scalability | ✅ Automatic | ❌ Manual scaling, potential downtime |
| Security Updates | ✅ Automatic | ❌ You must patch and maintain |
| SSL/TLS Certificates | ✅ Managed | ❌ Manual renewal and configuration |
| Monitoring & Analytics | ✅ Built-in dashboard | ❌ Build or integrate your own |
| Support | ✅ Dedicated team | ❌ You're on your own |
| Cost | Predictable monthly fee | Hidden costs: servers, bandwidth, DevOps time |
The bottom line: Self-hosting might seem "free," but the hidden costs of infrastructure, maintenance, security, and DevOps time quickly add up. Most teams find that Turbopush pays for itself in the first month just from saved engineering hours.
Step 1: Create Your Turbopush Account
Head over to https://app.turbopush.org/sign-up and create your free account. The setup takes less than a minute.
Step 2: Install the Turbopush CLI
Replace the AppCenter CLI with the Turbopush CLI in your project:
# Remove old AppCenter CLI (if installed globally)
npm uninstall -g appcenter-cli
# Install Turbopush CLI
npm install --save-dev @turbopush/cli
# or
yarn add -D @turbopush/cli
# or
pnpm add -D @turbopush/cli
Verify the installation:
npx turbopush --version
Step 3: Authenticate with Turbopush
Log in to your new Turbopush account:
npx turbopush login
This will:
- Open your browser for authentication
- Generate a secure access key
- Prompt you to paste the key in your terminal
Verify you're logged in:
npx turbopush whoami
Set Your Default Organization
npx turbopush org set <your-organization-slug>
Not sure what your organization slug is? List them all:
npx turbopush org list
Step 4: Register Your Apps in Turbopush
Create separate apps for iOS and Android (just like you had in AppCenter):
npx turbopush app add MyApp-iOS --appSlug myapp-ios
npx turbopush app add MyApp-Android --appSlug myapp-android
After creating each app, you'll receive deployment keys:
┌────────────┬─────────────────────────────────────┐
│ Name │ Deployment Key │
├────────────┼─────────────────────────────────────┤
│ Production │ dk_19ffa8fc2a91f2cd9afb3bfecafef06d │
├────────────┼─────────────────────────────────────┤
│ Staging │ dk_5g5dc7aa6197c1f292cd12ca28f39bb3 │
└────────────┴─────────────────────────────────────┘
Save these keys! You'll need them in the next steps.
Step 5: Update Your Dependencies
Replace the old CodePush package with Turbopush's version:
# Remove old package
npm uninstall react-native-code-push
# or
yarn remove react-native-code-push
# Install Turbopush SDK
npm install @turbopush/react-native-code-push
# or
yarn add @turbopush/react-native-code-push
Step 6: Update iOS Configuration (Swift)
6.1 Update CocoaPods
Run pod install to get the new Turbopush native module:
cd ios && pod install && cd ..
6.2 Check your AppDelegate.swift
Open ios/[YourProject]/AppDelegate.swift and check if you have the following import:
import React
import CodePush // Same import - Turbopush is compatible!
override func bundleURL() -> URL? {
#if DEBUG
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
CodePush.bundleURL() // No change needed!
#endif
}
The import and method calls remain the same because Turbopush maintains full CodePush API compatibility.
6.3 Update Info.plist
Open ios/[YourProject]/Info.plist and update the deployment key:
<key>CodePushDeploymentKey</key>
<string>YOUR_NEW_TURBOPUSH_IOS_DEPLOYMENT_KEY</string>
Replace YOUR_NEW_TURBOPUSH_IOS_DEPLOYMENT_KEY with the key from Step 4.
6.4 Verify iOS Deployment Target
Make sure your ios/Podfile has the minimum deployment target:
platform :ios, '15.5'
Step 7: Update Android Configuration (Kotlin)
7.1 Update build.gradle
In your android/app/build.gradle, update the CodePush gradle file reference at the end:
apply from: "../../node_modules/react-native-code-push/android/codepush.gradle"
apply from: "../../node_modules/@turbopush/react-native-code-push/android/codepush.gradle"
7.2 Update MainApplication.kt
For React Native 0.76+, update your android/app/src/main/java/.../MainApplication.kt:
import com.facebook.react.ReactHost
import com.facebook.soloader.SoLoader
import com.microsoft.codepush.react.CodePush // Same import!
class MainApplication : Application(), ReactApplication {
override val reactNativeHost: ReactNativeHost =
object : DefaultReactNativeHost(this) {
override fun getJSBundleFile(): String {
return CodePush.getJSBundleFile() // No change needed!
}
};
override fun onCreate() {
super.onCreate()
val deploymentKey = getString(R.string.CodePushDeploymentKey)
CodePush.getInstance(deploymentKey, this, BuildConfig.DEBUG)
loadReactNative(this)
}
}
7.3 Update strings.xml
Update android/app/src/main/res/values/strings.xml with your new deployment key:
<string name="CodePushDeploymentKey">YOUR_NEW_TURBOPUSH_ANDROID_DEPLOYMENT_KEY</string>
Replace YOUR_NEW_TURBOPUSH_ANDROID_DEPLOYMENT_KEY with the key from Step 4.
Step 8: Update JavaScript Code
The JavaScript integration is nearly identical. Update your import statement:
import codePush from "react-native-code-push";
import codePush from "@turbopush/react-native-code-push";
Your codePush() wrapper and all options remain the same:
import codePush from "@turbopush/react-native-code-push";
function App() {
// Your app code
return (
// Your components
);
}
// All your existing options still work!
export default codePush({
updateDialog: true,
installMode: codePush.InstallMode.IMMEDIATE
})(App);
Step 9: Build and Test
Rebuild your app to apply the native changes:
# For iOS
cd ios && pod install && cd ..
npx react-native run-ios --mode Release
# For Android
npx react-native run-android --mode release
Step 10: Release Your First Update with Turbopush
Now let's verify everything works by pushing an update:
# For iOS
npx turbopush release-react myapp-ios ios -t "1.0.0"
# For Android
npx turbopush release-react myapp-android android -t "1.0.0"
Make sure the version matches your app's current version in Info.plist (iOS) or build.gradle (Android).
Release with Options
The CLI options are similar to what you're used to:
npx turbopush release-react myapp-ios ios \
--deploymentName Production \
--description "First Turbopush release" \
--mandatory \
--rollout 50 \
--targetBinaryVersion "1.0.0"
Migration Checklist
Use this checklist to ensure you haven't missed anything:
- Created Turbopush account
- Installed
@turbopush/cli - Authenticated with
turbopush login - Created apps for iOS and Android
- Replaced
react-native-code-pushwith@turbopush/react-native-code-push - Updated
ios/Podfiledeployment target to 15.5+ - Ran
pod install - Updated
Info.plistwith new iOS deployment key - Updated
android/app/build.gradlewith new gradle path - Updated
strings.xmlwith new Android deployment key - Updated JavaScript imports
- Built and tested app in Release mode
- Successfully pushed first update
Troubleshooting
"No update available" after release
- Double-check your deployment keys are correct
- Verify the target binary version matches your app version exactly
- Make sure you're targeting the right deployment (Staging vs Production)
Build fails after migration
- Run
cd ios && pod install && cd ..to refresh CocoaPods - Clean your build:
cd android && ./gradlew clean && cd .. - For iOS, clean in Xcode: Product → Clean Build Folder
Updates not installing
- Verify
codePush()is wrapping your root component - Check your app is running in Release mode (Debug mode doesn't check for updates)
- Review device logs for CodePush-related messages
What About My Release History?
Your release history from AppCenter won't be automatically migrated to Turbopush. However, this is usually not a problem because:
- Active users will get new updates - Once you push your first Turbopush release, users will receive it
- No disruption - Users won't experience any downtime during the transition
- Fresh start - This is an opportunity to clean up old releases
Simply release your current app state as your first Turbopush release, and you're back in business.
Managing Releases via Dashboard
While the CLI is powerful, you can also manage everything through the Turbopush web dashboard at https://app.turbopush.org.
The dashboard provides:
- Visual deployment history - See all releases with timestamps and descriptions
- Real-time metrics - Track downloads and installations
- Version distribution - See which versions your users are running
- One-click rollbacks - Instantly revert problematic updates
- Team collaboration - Manage access and permissions
Wrapping Up
Migrating from AppCenter CodePush to Turbopush is straightforward because we've built Turbopush to be a drop-in replacement. The hardest part is updating a few configuration files—your core integration code stays virtually unchanged.
With AppCenter's shutdown, you have a choice: spend days or weeks setting up and maintaining self-hosted infrastructure, or spend 30 minutes migrating to Turbopush and get back to building your app.
Ready to migrate? Here are your next steps:
Happy shipping! 🚀