AeroPush
The React Native CodePush alternative

Ship React Native
updates instantly.

The best CodePush alternative and App Center replacement. Push app updates over the air with 99% smaller patches — no App Store or Play Store review delays. Self-hosted, with a managed-grade dashboard: staged rollouts, crash intelligence and one-click rollback.

No store review Instant rollback Fingerprint-safe Self-hosted
bundle v14
9:41 live
Acme Store
v13 · JS bundlev14 · JS bundle
Summer sale · 30% off
Checking for updates…
Downloading v14OTA
Updated to v14
No reinstall · no store review
terminal
$ npm install react-native-aeropush
$ npx aeropush release --channel production
✓ bundle v14 uploaded · fingerprint matched · rolling out to 48,210 devices

Set it up with AI

Paste this prompt into Claude Code, Cursor, or any coding agent inside your app — it installsreact-native-aeropushand configures iOS, Android & JavaScript for you. Replace<YOUR_APP_KEY>with your project’s access token (open a project → Access tokens).

You are setting up the AeroPush over-the-air (OTA) update SDK in this React Native app. Do everything end to end — install the package, wire the native iOS + Android bundle hooks, initialise it in JavaScript, and bake in the native fingerprint. Detect the project's React Native version and app names first, then adapt each step to them.

App key: <YOUR_APP_KEY>
Channel: production
Server: https://aeropush.tech

1. INSTALL
   - Run: npm install react-native-aeropush   (use yarn/pnpm if this project does)
   - It's a New Architecture Turbo Module — React Native Codegen generates the native interface on the next build. No manual linking.

2. iOS
   - Run: cd ios && pod install
   - Create a bridging header ios/<AppName>/<AppName>-Bridging-Header.h containing:  #import "Aeropush.h"
     (If one already exists, just add that import.)
   - In Build Settings → "Objective-C Bridging Header", point BOTH Debug and Release configs at it.
   - In the AppDelegate (ReactNativeDelegate on RN 0.77+), override the bundle URL so release builds boot from the staged OTA bundle:
       override func bundleURL() -> URL? {
       #if DEBUG
         RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
       #else
         Aeropush.bundleURL() ?? Bundle.main.url(forResource: "main", withExtension: "jsbundle")
       #endif
       }
     On RN 0.77+ also override sourceURL(for:) to return self.bundleURL().

3. ANDROID
   - In MainApplication.kt add:  import com.aeropush.AeropushModule
   - In the ReactHost / getDefaultReactHost setup, set the JS bundle path so release builds use the staged bundle:
       jsBundleFilePath = if (BuildConfig.DEBUG) null else AeropushModule.getJSBundleFile(applicationContext)
     (Older template: override getJSBundleFile() to return AeropushModule.getJSBundleFile(applicationContext) in release, null in debug.)

4. JAVASCRIPT (App entry, e.g. App.tsx)
   - Initialise once at module scope, before the component tree renders:
       import AeroPush, { AeroPushBoundary, InstallMode } from 'react-native-aeropush';
       AeroPush.init({ appKey: '<YOUR_APP_KEY>', channel: 'production' });
       AeroPush.sync({ installMode: InstallMode.ON_NEXT_RESTART });
   - Wrap the root component in <AeroPushBoundary> … </AeroPushBoundary> (this crash-guard marks a bundle healthy on a successful mount and rolls back on a render crash). If you can't use the boundary, call AeroPush.markBundleHealthy() after a successful mount instead.

5. NATIVE FINGERPRINT (compatibility gating)
   - Run: npx aeropush fingerprint embed
     This bakes the native fingerprint into the iOS Info.plist and Android build.gradle and adds a build-phase/Gradle step so it re-bakes on every build. On Android, ensure buildFeatures { buildConfig true }.

6. VERIFY
   - Make a RELEASE build (OTA only affects release builds — debug always loads from Metro).
   - Publish a test bundle and relaunch:
       export AEROPUSH_APP_KEY=<YOUR_APP_KEY>
       npx aeropush release --channel production
   - The app should pick up the new bundle on its next cold launch.

Make the minimal edits needed, keep existing formatting/config intact, and after each native change explain what you did. If any RN version detail differs from the above, adapt accordingly.

How it works

From your laptop to every phone — in seconds.

AeroPush ships the JavaScript half of your app over the air. Your native binary stays put; only the bundle travels — signed, fingerprint-checked and reversible.

App Store review · 1–7 days
Your JS bundle
aeropush release
AeroPush
signed · fingerprinted
Live on devices
seconds, not days

The control room

See every release, live.

Adoption, crash-free rate, rollout progress and per-version status — the moment a bundle goes out, you watch it land.

aeropush.tech/v1/dashboard
Release · production
Acme Store · v14
rolling out
48,210
active devices
92.4%
adoption
99.98%
crash-free
1.9 MB
bundle size
Adoption · last 14 daysinstalls / day
Rollout
78%
of fleet
v14active
v13replaced
v12rolled back

New binary on the store

OTA can’t ship native code.
So tell them to update.

When a release changes native code, it has to go through the store. AeroPush prompts the users still sitting on an old binary — a dismissible banner, or a blocking modal for the release you can’t let anyone skip. Configured per app version, from the dashboard, with no app update required to change it.

  • Force or let them dismissChoose per version. A forced prompt blocks the app; an optional one snoozes for 24h and comes back.
  • Nobody gets locked outAeroPush never forces a device whose OS can’t install the new build — it softens to optional instead of trapping the user.
  • Store installs onlyPrompts reach real App Store and Play installs, never TestFlight or sideloaded builds that have no listing to open.
  • One switch to silence itA kill switch stops every prompt instantly — no release, no store review.
Acme Store 3.0
Time to update

Version 3.0 is available on the App Store.

What’s New
  • Faster launch
  • Redesigned checkout
  • Crash fixes
Update now
required update
or a slim banner
Update available
Version 3.0 is on the App Store.
Update✕

Why AeroPush

Built to ship safely.

Native fingerprint guard

Devices only ever receive a bundle their binary can actually run. Strict two-way generational isolation, computed automatically.

Automatic crash rollback

A three-layer crash guard pulls a bad bundle and restores the last-good version — on every plan.

Bundle-id scoping

Each app is locked to its real bundle id and package. Mismatched clients are refused at the door.

Staged rollouts

Release to 5%, watch, then dial to 100% — or pause instantly. Ship with confidence, not hope.

Crash intelligence

Adoption, crash layers and top error messages per release, so you know exactly what's misbehaving.

Teams & roles

Organisation workspaces, RBAC and shareable invite links for your whole engineering team.

FAQ

Good questions

A self-hosted OTA platform for React Native — a modern CodePush replacement. Push JS bundle updates straight to installed apps, skipping the App Store / Play Store review cycle.

That's the whole point. Every bundle is scoped to your app's bundle id, checked against the binary's native fingerprint, and guarded by automatic crash rollback — so a bad or incompatible update never sticks.

CodePush is retired. AeroPush gives you the same instant-update workflow plus native-fingerprint compatibility gating, crash intelligence, staged rollouts, team roles and your own infrastructure.

Yes — Starter is free forever: 1 app, 1,000 monthly active devices, automatic crash rollback and 5 releases a month. No credit card required.

Ship your next release in seconds.

Free 1,000 MAU · no credit card · 5-minute setup.

$ npm install react-native-aeropush