@vexor_ai/react-native-codepush-ota
v0.1.18
Published
Vexor OTA helper SDK for react-native-ota-hot-update and self-hosted CodePush manifests.
Readme
@vexor_ai/react-native-codepush-ota
Small React Native helper SDK for Vexor's self-hosted CodePush OTA flow.
It wraps:
@vexor_ai/react-native-ota-hot-updatereact-native-blob-util- Vexor Admin OTA manifest endpoint
Install
React Native 0.76+:
pnpm add @vexor_ai/react-native-codepush-ota react-native-blob-utilReact Native 0.73 / 0.74 / 0.75:
pnpm add @vexor_ai/react-native-codepush-ota [email protected][email protected]+ targets newer React Native versions, so pin 0.21.2 for RN 0.73-0.75.
Usage
import {
checkPendingUpdate,
checkUpdate,
configure,
installUpdate,
notifyApplicationReady,
reset,
} from '@vexor_ai/react-native-codepush-ota';
configure({
baseUrl: 'https://admin-cp.vexor.one',
deploymentKey: '<deployment-key-from-admin>',
binaryVersion: '1.0.0',
clientId: '<stable-device-or-install-id>',
});
await checkPendingUpdate();
await notifyApplicationReady();
const update = await checkUpdate();
if (update.hasUpdate) {
await installUpdate(update, {
restartAfterInstall: true,
downloadRetryAttempts: 3,
downloadRetryDelayMs: 1500,
onProgress: (received, total) => console.log(received, total),
});
}
reset(true);Pass a stable clientId per device/install for CodePush Server metrics. The SDK reports downloads, successful installs,
and failed installs automatically during installUpdate and sync.
Bundle downloads are retried before a failed deploy is reported. The default is 2 attempts with a short backoff; tune
downloadRetryAttempts, downloadRetryDelayMs, and onDownloadAttempt for large bundles or poor mobile networks.
If clientId is omitted, the SDK generates one and stores it through the configured storage adapter. For production,
pass your own stable install/device id or provide durable storage.
updateMode controls the install flow:
forcedownloads and restarts immediatelybackgrounddownloads silently and restarts immediatelydeferreddownloads silently and applies on the next app launchpromptlets the app show its own Install now / Install next launch dialog
For rollback detection, call checkPendingUpdate() as early as possible after configure(), then call
notifyApplicationReady() after your app has booted successfully. If a previous launch saw a pending update but never
called notifyApplicationReady(), the next checkPendingUpdate() reports DeploymentFailed and calls
removeUpdate(false) by default.
One-shot sync
import { configure, sync } from '@vexor_ai/react-native-codepush-ota';
configure({
deploymentKey: '<production-deployment-key>',
binaryVersion: '1.0.0',
clientId: '<stable-device-or-install-id>',
});
await sync({
onSuccess: () => console.log('OTA installed'),
});When the manifest uses updateMode: "prompt", sync() returns the update without installing it so the app can show its own confirmation UI.
Production checklist
- Use the deployment-key manifest endpoint from Admin UI instead of the app/deployment fallback.
- Pass a stable
clientIdfor metrics and rollout bucketing. - Call
checkPendingUpdate()before rendering the main app tree. - Call
notifyApplicationReady()only after the app has booted successfully. - Tune
downloadRetryAttemptsanddownloadRetryDelayMsfor large bundles on unstable mobile networks. - Release through an Admin UI access key or
CODEPUSH_TOKEN; avoid account/password automation.
Native setup
This SDK handles manifest checking and bundle installation calls, and it pulls the forked native bundle loader @vexor_ai/react-native-ota-hot-update transitively.
Forked native loader docs:
- https://github.com/vantuan88291/react-native-ota-hot-update
- https://github.com/vantuan88291/react-native-ota-hot-update/blob/main/DOC_OTA_SERVER.md
iOS, React Native below 0.77
In ios/<AppName>/AppDelegate.mm or AppDelegate.m:
#import "OtaHotUpdate.h"
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
return [OtaHotUpdate getBundle];
#endif
}iOS, React Native 0.77+
In ios/<AppName>/AppDelegate.swift:
import react_native_ota_hot_update
override func bundleURL() -> URL? {
#if DEBUG
RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
OtaHotUpdate.getBundle()
#endif
}Android
In android/app/src/main/java/.../MainApplication.kt, pass the OTA bundle path to React Native in release mode.
For modern Kotlin templates this usually means overriding reactNativeHost / getJSBundleFile depending on your RN version:
import com.otahotupdate.OtaHotUpdate
override fun getJSBundleFile(): String? {
return if (BuildConfig.DEBUG) {
super.getJSBundleFile()
} else {
OtaHotUpdate.bundleJS(applicationContext)
}
}If your generated template is different, follow the Android section in the upstream react-native-ota-hot-update README and keep the same rule: debug uses Metro, release uses OtaHotUpdate.bundleJS(applicationContext).
iOS pods
After installing dependencies:
cd ios
pod installRelease-mode note
OTA bundles are loaded in release mode. Debug mode continues to load Metro, so test installed OTA behavior with a release/scheme build.
