Skip to main content
Live. This area is documented as current, user-reliable behavior.

Goal

Publish an update to a channel, watch adoption, and roll back instantly if something goes wrong.

Prerequisites

  • mobile_ota is enabled on the plan
  • For code push: an Expo or React Native app

Workflow

1
Point your app at the update endpoint: Expo apps use the standard expo-updates protocol against /ota/expo/<app-slug>/manifest; any app can poll /ota/config/<app-slug> for JSON remote configuration.
2
Publish updates from your pipeline with an ota_publish step, from CI with the ota:publish token scope, or by uploading a bundle.
3
Pin updates to channels per platform and runtime version; use staged rollouts to expose a new update gradually.
4
Roll back a bad update in one click — or let auto-rollback do it when clients report failures.

Two kinds of updates

  • code_push: a full JavaScript bundle for Expo and React Native apps, served over the expo-updates protocol with RSA signing.
  • config: a JSON document any app can poll — feature flags, kill switches, copy changes — no particular framework required.

Safety controls

  • Channels and runtime versions keep updates away from binaries that cannot run them.
  • Staged rollouts serve a new update to a cohort percentage before everyone.
  • Auto-rollback unpins an update when clients report enough failures.
  • Update history per channel makes every pin, promote, and rollback auditable.

Adoption analytics

Clients report manifest checks, downloads, applies, and failures, so each update shows real adoption. Observe ties crash-free rates to the update group, so you can see whether an over-the-air fix actually fixed things.

Expected result

A fix reaches installed apps in minutes, with per-update adoption numbers and an instant path back.

Common failures

  • Clients never see an update: the channel, platform, or runtime version does not match what the app requests.
  • Publishing fails for a Flutter app: code push is JavaScript-only; Flutter apps can still use JSON remote configuration.
  • Signed update verification fails: the app pins an old signing key — rotate keys carefully and ship the new public key first.