Ship Expo Updates (OTA) in Minutes: A Complete Turbopush Getting Started Guide
If you've ever needed to fix a critical bug in your Expo app without waiting for App Store review, or wanted to roll out features instantly to your users, you're in the right place. Turbopush makes Over-The-Air (OTA) updates simple, fast, and reliable.
Looking for a cost-effective alternative to EAS Updates? Turbopush offers the same power and flexibility at a fraction of the cost, with additional features like gradual rollouts, instant rollbacks, and detailed analytics.
This guide will walk you through setting up Turbopush in your Expo project from scratch. Whether you're new to Over-The-Air updates or migrating from another solution, you'll be shipping updates in no time.
What is Turbopush?โ
Turbopush is an Over-The-Air (OTA) update platform that lets you push JavaScript bundle updates directly to your users' devices without going through app store reviews. Think of it as a deployment pipeline for your mobile app's code - similar to how you deploy web apps, but for React Native and Expo.
Perfect for:
- Bug fixes that can't wait for app store approval
- A/B testing new features
- Gradual rollouts to specific user segments
- Quick iterations during development
๐ Want to See It in Action First?โ
Before diving into the setup, you can test OTA updates right now with our pre-built Expo example app. No configuration needed - just scan and experience instant updates:
This working example lets you:
- See how OTA updates download and install
- Test mandatory vs. optional updates
- Experience rollback functionality
- Check update status in real-time
Takes less than 2 minutes to try. Once you see it working, you'll know exactly what you're building!
โ ๏ธ Important: Turbopush does NOT work with Expo Go
Due to technical limitations, Turbopush requires native code modifications that aren't possible in the Expo Go app. You'll need to create a custom development build with npx expo prebuild,
This is a one-time setup. Once you have a custom build installed on your device, OTA updates will work seamlessly.
Step 1: Install the Turbopush CLIโ
The Turbopush CLI is your command center for managing releases. Install it as a dev dependency in your project:
npm install --save-dev @turbopush/cli
# or
yarn add -D @turbopush/cli
# or
pnpm add -D @turbopush/cli
Verify the installation worked:
npx turbopush --version
You should see the CLI version printed out. If you do, you're good to go!
Step 2: Create Your Turbopush Accountโ
Head over to https://app.turbopush.org/sign-up and create your free account. The process is straightforward - just your email and you're in.
Step 3: Authenticate the CLIโ
Now let's connect your local CLI to your Turbopush account:
npx turbopush login
This command will:
- Open your browser for authentication
- Generate a secure access key
- Prompt you to paste that key back in your terminal
Once you see a success message, verify you're logged in:
npx turbopush whoami
Set Your Default Organizationโ
If you're working with a team or have multiple organizations, set your default:
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โ
Here's an important detail: you need to create separate apps for iOS and Android. This ensures each platform gets the right update packages.
npx turbopush app add MyApp-iOS --appSlug myapp-ios
npx turbopush app add MyApp-Android --appSlug myapp-android
The --appSlug parameter is optional but recommended. It's used to identify your app in the CLI and API. If you don't provide it, Turbopush will generate one from your app name.
Save Your Deployment Keysโ
After creating each app, you'll see output like this:
โโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Name โ Deployment Key โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Production โ dk_19ffa8fc2a91f2cd9afb3bfecafef06d โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ Staging โ dk_5g5dc7aa6197c1f292cd12ca28f39bb3 โ
โโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Write these keys down! You'll need them in the next step. Each app gets two deployment keys:
- Staging: For testing updates before going live
- Production: For your production users
Step 5: Install the Turbopush SDKโ
Now let's add Turbopush to your Expo project:
npx expo install @turbopush/react-native-code-push @turbopush/turbopush-expo-plugin expo-build-properties
This installs three packages:
@turbopush/react-native-code-push: The core SDK@turbopush/turbopush-expo-plugin: Expo configuration pluginexpo-build-properties: To set the minimum iOS deployment target (15.5 required)
Step 6: Configure Your Appโ
Open your app.json (or app.config.js) and add the Turbopush configuration:
{
"expo": {
"plugins": [
[
"expo-build-properties",
{
"ios": {
"deploymentTarget": "15.5"
}
}
],
[
"@turbopush/turbopush-expo-plugin",
{
"android": {
"CodePushDeploymentKey": "your-android-staging-key"
},
"ios": {
"CodePushDeploymentKey": "your-ios-staging-key"
}
}
]
]
}
}
Replace your-android-staging-key and your-ios-staging-key with the actual keys from Step 4.
Note: The expo-build-properties plugin sets the iOS deployment target to 15.5, which is required by Turbopush. If you're already targeting iOS 15.5 or higher, you can skip this plugin.
Pro tip: Use environment variables for deployment keys so you can easily switch between Staging and Production:
Step 7: Run Prebuildโ
Before building, you need to generate the native code with prebuild:
npx expo prebuild
This command generates the ios and android folders with all the necessary native configurations from your plugins.
Step 8: Integrate CodePush in Your Codeโ
The final code step is to wrap your app with the CodePush higher-order component. This is what checks for and downloads updates.
Open your root component (usually App.tsx or App.js) and add:
import codePush from "@turbopush/react-native-code-push";
function App() {
// Your app code here
return (
// Your app components
);
}
export default codePush(App);
That's it for the code! The codePush() wrapper automatically handles checking for updates when your app starts.
Want More Control?โ
You can customize the update behavior by passing options directly to the codePush() wrapper:
Interactive updates (show dialog and install immediately):
import codePush from "@turbopush/react-native-code-push";
function App() {
// Your app code
return (
// Your app components
);
}
export default codePush({
updateDialog: true,
installMode: codePush.InstallMode.IMMEDIATE
})(App);
Custom update dialog:
export default codePush({
updateDialog: {
title: "Update Available",
optionalUpdateMessage: "A new version is available. Install now?",
optionalInstallButtonLabel: "Install",
optionalIgnoreButtonLabel: "Later"
},
installMode: codePush.InstallMode.IMMEDIATE
})(App);
Step 9: Build and Run Your Appโ
Before you can push updates, you need to build and run your app at least once. This creates the native binary that will receive updates:
# For iOS (simulator or device) - Release mode
npx expo run:ios --configuration Release
# For Android (emulator or device) - Release mode
npx expo run:android --variant release
Important: We're using --configuration Release (iOS) and --variant release (Android) to build in production mode. This ensures the app behaves exactly like it will in production with OTA updates enabled.
This will compile the native code and install the app on your simulator/emulator or device. This is your baseline - all future OTA updates will be applied to this binary.
Step 10: Release Your First Updateโ
Now for the exciting part - pushing your first update! Make a small change to your app (add some text, change a color, whatever you want to test).
Then release it to Turbopush using the Expo-specific command:
# For iOS (replace "1.0.0" with your app version)
npx turbopush release-expo myapp-ios ios "1.0.0"
# For Android
npx turbopush release-expo myapp-android android "1.0.0"
The CLI will:
- Bundle your JavaScript code using Expo's bundler
- Upload it to Turbopush
- Make it available to your app immediately
Important: The version number ("1.0.0") must match exactly what's in your app.json under expo.version.
Release with Optionsโ
You can customize your release with additional parameters:
npx turbopush release-expo myapp-ios ios "1.0.0" \
--deploymentName "Production" \
--description "Critical bug fixes" \
--mandatory \
--rollout 50
Parameters:
--deploymentNameor-d: Target deployment (default: "Staging")--descriptionor--des: Release notes--mandatoryor-m: Force users to install this update--rolloutor-r: Gradual rollout percentage (e.g., 25 = 25% of users)
Step 11: Test Your Updateโ
Open your app on the test device. You should see one of these scenarios:
- Immediate update (mandatory): If your app was closed, it downloads and applies the update on restart
- Background update (non-mandatory): If your app was running, it downloads the update and applies it on the next restart
Check your device logs to see the update process in action. You should see messages about checking for updates, downloading, and installing.
Common Issues and Quick Fixesโ
No updates availableโ
- Double-check your deployment keys are correct
- Verify you're targeting the right deployment (Staging vs Production)
- Make sure your app version matches the release target version
Binary version mismatchโ
Your release target version must match exactly what's in your app.json. If your app is 1.0.0, release to 1.0.0, not 1.0.1.
Updates not installingโ
Make sure codePush() is wrapping your root component. The wrapper is what enables the update functionality.
What's Next?โ
Congratulations! You've successfully set up Turbopush and pushed your first OTA update. Here are some things to explore next:
Multi-Deployment Strategyโ
Use Staging for testing and Production for live users:
# Test on staging first
npx turbopush release-expo myapp-ios ios "1.0.0" -d Staging
# Once verified, promote to production
npx turbopush promote myapp-ios Staging Production
Monitor Your Releasesโ
Check your deployment history and see how users are adopting updates:
npx turbopush deployment history myapp-ios Production
Manage Updates via Dashboardโ
While the CLI is powerful, you can also manage and monitor everything through the Turbopush web dashboard at https://app.turbopush.org.
The dashboard gives you:
- Visual deployment history: See all your releases with timestamps, descriptions, and rollout percentages
- Real-time metrics: Track how many users have downloaded and installed each update
- Version distribution: See which versions your users are running
- Easy rollbacks: Rollback problematic updates with a single click
- Team collaboration: Manage team access and permissions
This is particularly useful when you need to quickly check the status of a deployment or share insights with non-technical team members who might not be comfortable with the CLI.
Advanced Update Strategiesโ
- Mandatory updates: Force users to install critical fixes
- Gradual rollouts: Release to 10% of users, then 50%, then 100%
- Target specific versions: Send different updates to different app versions
Why Turbopush?โ
If you've used other OTA update solutions, here's what makes Turbopush different:
Cost-Effective Alternative to EAS Updates: Get the same power and flexibility at a fraction of the cost. Turbopush offers all the OTA capabilities you need without the premium pricing of Expo's EAS Updates.
100% CodePush Compatible: Drop-in replacement for AppCenter CodePush. No code changes needed - just update your deployment keys.
Universal Platform Support: Works with bare React Native, Expo, and the New Architecture (Fabric + TurboModules).
Rich Analytics Dashboard: Track install rates, version adoption, rollback events, and detailed user metrics in real-time.
Affordable Pricing: Pay-as-you-grow with a generous free tier. Significantly more cost-effective than EAS Updates without compromising features.
Advanced Features: Gradual rollouts, instant rollbacks, version targeting, mandatory updates, and delta updates for minimal bandwidth usage.
Modern Developer Experience: Beautiful CLI, TypeScript SDK, comprehensive docs, and excellent support.
Wrapping Upโ
OTA updates are a game-changer for mobile development. What used to take days (or weeks) of app store review now takes seconds. Bug fixes, feature flags, A/B tests - all deployable instantly.
Turbopush makes this power accessible with a simple CLI and minimal setup. You went from zero to shipping updates in about 10 steps, and now you have a deployment pipeline that rivals web development.
Want to learn more? Check out:
Happy shipping! ๐