React Native OTA SDK Reference

Every method, install mode and no-update reason in the @otaupdate/react-native SDK.

Everything is exported from @otaupdate/react-native, both named and on the default export:

ts
import OtaUpdate, { withOtaUpdate, useOtaUpdate, InstallMode, SyncStatus } from '@otaupdate/react-native';

Functions and components

ExportPurpose
withOtaUpdate(App, options?)Root-component wrapper. The whole integration for most apps.
sync(options?)Check → download → install. Concurrent calls share one run. Resolves to a SyncStatus; never throws.
checkForUpdate(key?)Just the check. Returns { update, reason }.
notifyAppReady()Confirms the running bundle. Required, or the update reverts on the next launch.
restartApp(onlyIfPending?)Reloads the JS bundle, applying a pending install now.
getCurrentPackage()The running OTA package, or null when running the bundle from the binary.
clearUpdates()Wipes every download and reverts to the bundle in the binary. Handy in development.
startAutoSync(options?)The launch/resume loop withOtaUpdate uses. Returns a teardown function.
useOtaUpdate(options?)Hook for update UI: { status, progress, available, error, isSyncing, check, update }.
getConfig()The resolved configuration: key, server, app version, channel, platform, running label.
isNativeModuleAvailablefalse in Expo Go and on web — every call would otherwise throw.
OtaApiErrorThrown for server-side failures; carries an HTTP status.

sync() options

OptionDefaultMeaning
installModeON_NEXT_RESTARTWhen a normal update swaps in.
mandatoryInstallModeIMMEDIATEWhen a release published with --mandatory swaps in.
minimumBackgroundDuration0Seconds backgrounded before an ON_NEXT_RESUME install applies.
onSyncStatusChange—Called with each SyncStatus as the run progresses.
onDownloadProgress—Called with { receivedBytes, totalBytes } during download.
shouldInstall—Return false to skip this update. Mandatory releases ignore it.
deploymentKeyfrom native configOverride the key for this call. Rarely needed.

withOtaUpdate() / startAutoSync() options

OptionDefaultMeaning
checkOnAppStarttrueSync once when the app starts.
checkOnResumetrueSync each time the app returns to the foreground.
minimumSyncInterval60Minimum seconds between automatic syncs.
sync{}The sync() options above, used for every automatic sync.

Install modes

ModeWhen the new bundle loads
InstallMode.ON_NEXT_RESTARTDefault. The next cold start. Never interrupts.
InstallMode.ON_NEXT_RESUMENext foreground, after minimumBackgroundDuration seconds backgrounded.
InstallMode.IMMEDIATERight away with a JS reload. Reserved for mandatory fixes.

Sync statuses

SyncStatus values arrive through onSyncStatusChange and are what sync() resolves to. SyncStatus[value] gives you the name for logging.

StatusMeaning
CHECKING_FOR_UPDATEAsking the server.
AWAITING_USER_ACTIONWaiting on your shouldInstall callback.
DOWNLOADING_PACKAGEFetching and verifying the bundle.
INSTALLING_UPDATEApplying it according to the install mode.
UPDATE_INSTALLEDDone — live now, or on the next restart.
UP_TO_DATENothing applicable for this device.
UPDATE_IGNOREDshouldInstall returned false.
SYNC_IN_PROGRESSAnother sync was already running; this call joined it.
UNKNOWN_ERRORThe run failed. The error is logged and reported; the app carries on.

No-update reasons

checkForUpdate() returns a reason when there is nothing to install:

ReasonMeaning
up_to_dateAlready on the newest applicable release.
not_in_rolloutA newer release exists but this device is outside its rollout.
no_release_for_runtimeNo release on this channel targets this native app version.
platform_disabledThis platform is switched off for the project.
unknown_channelThe key resolved but the channel it names no longer exists.

Native entry points

These are the calls your MainApplication and AppDelegate make — the Expo plugin wires them for you. Each resolves the bundle for this launch and advances the rollback state machine, so call them exactly where React Native asks for its bundle and nowhere else.

PlatformCallNotes
AndroidOtaUpdate.getJSBundleFile(context)Returns null for "use the bundle in the APK". A second overload takes the asset bundle name if yours is not index.android.bundle.
iOS[OtaUpdate bundleURL]bundleURLForResource:withExtension: covers a binary bundle that is not main.jsbundle; binaryBundleURL ignores downloads entirely.

A broken OTA state cannot stop your app from starting

If bundle resolution throws for any reason, both platforms log it and fall back to the bundle inside the binary. On Expo, the handler also returns null whenever developer support is on, so a downloaded bundle never shadows your Metro live-reload in a debug build.

Package shapes

TypeFields
RemotePackagelabel, packageHash, downloadUrl, size, isMandatory, description, targetBinaryVersion, rollout, isRollback, deployment, download(onProgress?)
LocalPackagelabel, packageHash, isMandatory, description, bundlePath, size, install(mode?, minimumBackgroundDuration?)
CurrentPackagelabel, packageHash, description, isMandatory, bundlePath, appVersion, isPending, isFirstRun

label is the release number as a string — #14 — which is what the dashboard, ota status and your device logs all show.