Concepts

Core concepts behind CodePush and OTA updates

This section explains how CodePush works at a conceptual level before any setup or commands. Understanding the update model makes the configuration and release workflow easier to follow.


The Problem: Slow App Store Updates

By default, shipping a mobile app update looks like this:

Developer makes a change
→ Build a new app binary
→ Submit to App Store / Play Store
→ Wait for review
→ Users download the update

This process is slow and rigid:

  • Reviews can take hours or days
  • Urgent fixes are delayed
  • Users must manually update

The Idea: Over-the-Air (OTA) Updates with CodePush

CodePush enables OTA updates for React Native apps. Instead of distributing a new binary, the app downloads an updated JavaScript bundle from a server:

Developer releases JS update
→ CodePush server stores update
→ App checks server for updates
→ New bundle downloaded
→ Update applied on restart/resume/immediately

Typical OTA use cases:

  • Hotfixes for production bugs
  • UI tweaks or styling updates
  • Feature flag changes
  • Configuration or content updates
  • Experimentation or staged feature rollouts

Benefits: Faster releases, reduced dependency on app store reviews, and quicker fixes for users.

JavaScript layer vs Native layer

React Native apps contain two layers.

The Native layer is the compiled platform code, such as:

  • Swift / Objective-C for iOS
  • Java / Kotlin for Android

This includes platform integrations, native modules, permissions, OS APIs, and the compiled app binary. Changes to this layer require rebuilding the app and publishing through the app stores.

The JavaScript layer contains the React Native application logic:

  • UI components
  • business logic
  • navigation
  • state management
  • bundled static assets

CodePush updates this JavaScript bundle and its assets. As long as JS remains compatible with the already-installed native binary, it can be delivered as an OTA update.

What can and cannot be updated

✅ Can Be Updated via CodePush (OTA-safe):

  • Fixing JavaScript bugs
  • UI or layout adjustments
  • Styling changes
  • Updating bundled images or static assets
  • Feature flags or configuration logic
  • JavaScript performance improvements

These updates modify only the JavaScript bundle, so they can be safely delivered over the air.

❌ Require a New App Release

  • Adding or modifying native modules
  • Upgrading React Native or native dependencies
  • Editing native configuration files (build.gradle, Info.plist, etc.)
  • Changing app permissions (camera, location, etc.)
  • Adding platform-specific features or integrations

These changes affect compiled native code, so they must go through the App Store or Play Store.

How the update flow works

A CodePush-enabled app includes a client SDK that communicates with the update server:

app launch
* CodePush SDK checks for updates (based on configuration)
* update available?
* download JavaScript bundle + assets
* store update locally
* apply update (typically on next restart)

The update replaces the previously installed JavaScript bundle while keeping the native application unchanged.

If an update fails or causes the app to crash on startup before it is marked as successful, the client can automatically revert to the previous working bundle.

Deployment model

CodePush organizes updates using apps and deployments.

Each mobile application registered with CodePush is called an app. A project may contain multiple apps, such as:

  • MyApp-Android
  • MyApp-iOS

Separating apps by platform is recommended because React Native bundles differ between platforms.

Each app contains one or more deployments. Deployments represent release channels. Default deployments include Staging and Production.

release update → Staging
internal testing
promote update → Production

This workflow lets teams validate OTA updates before exposing them to all users. Creating, promoting, and changing those releases is done with the CodePush CLI, not from a web upload UI—see Releasing updates.

Deployment keys

Each deployment has a deployment key. The deployment key is embedded in the mobile app and tells the CodePush SDK which deployment to check for updates.

Example usage:

  • development builds use the Staging key
  • production builds use the Production key

This separation ensures test updates do not reach production users.

Where CodePush fits in the release process

Traditional mobile release:

commit
→ CI build
→ store submission
→ user installs update

Release workflow with CodePush:

commit
→ CI build
→ store release (initial binary)
→ OTA updates via CodePush
→ occasional store releases for native changes

This lets teams ship small fixes and improvements between full app store releases.