react-native-update for Hermes OTA delivery and rollback
🚀 Blazing fast hot updates (OTA) for React Native — Hermes-optimized diff patches, crash rollback, staged rollout. A CodePush alternative for iOS / Android / HarmonyOS.
At a glance
- What is it?
- react-native-update is a React Native OTA library and hosted update service for iOS, Android, and HarmonyOS. It supports Hermes-optimized differential patches, staged releases, crash rollback, telemetry, and native cold-start recovery, but its custom license and service dependency require review before adoption.
- Who is it for?
- Adopt react-native-update if your React Native applications already use Hermes and your team accepts an OTA service dependency plus the custom LICENSE terms. Do not assume its update policy covers native binary changes, and do not choose it without checking Hermes compatibility, supported React Native versions, rollback behavior, telemetry requirements, and the LICENSE file.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Where react-native-update fits in a React Native release process
react-native-update addresses application changes that do not require a new store submission, such as JavaScript and supported Hermes bundle content. Its intended users are React Native product teams that ship through iOS, Android, or HarmonyOS and need to publish corrections after a binary has reached devices. The repository describes the project as an alternative to Microsoft CodePush following the retirement of App Center on March 31, 2025.
The project is broader than a patch downloader. Its documentation lists update discovery, differential package delivery, activation policies, health marking, automatic rollback, release analytics, staged rollout by percentage, JavaScript error reporting, and a web dashboard. Command-line tools and open APIs are also mentioned as parts of the release workflow. That makes the project relevant to maintainers who need an operational process around an OTA release, rather than developers who only want to swap one JavaScript file at runtime.
The scope still has a boundary. The options reference distinguishes update checks from the native cold-start check used to recover devices on which JavaScript fails before it runs. It also provides `overridePackageVersion`, but the README does not state that every native change can be deployed OTA. An evaluation should therefore assume that the installed binary still constrains compatible updates. The README does not provide a general policy for changes to native dependencies, entitlements, signing, or platform binaries.
Hermes differential packages and multi-version delivery
The central technical choice is a differential update format aimed specifically at Hermes bytecode. The README says patch generation uses bsdiff or hdiff, and it reports that a one-line change can produce an approximately 3.4 KB package. These are project-provided figures rather than independent measurements. The stated design goal is to avoid sending a complete bundle whenever a small application change can be represented as a patch.
Package generation happens at build time. The README says applications already published in app stores can benefit after a rebuild, without receiving an earlier optimization retroactively. Multi-version delivery is another documented feature: when a device crosses several published versions, the client downloads one update package instead of applying every intermediate version sequentially. That reduces both download work and the number of patch application steps, although the README does not quantify the savings.
Hermes optimization is useful only when it aligns with the bundle format used by the application. The project also tracks React Native stable releases and supports the New Architecture, but it identifies an upstream compatibility gap: Android React Native 0.73.0 through 0.76.0 cannot use the New Architecture because of upstream issues. Versions below 0.73 and versions above 0.76.1 are supported for that architecture. An engineer evaluating a device population spanning several React Native releases should inspect the current documentation for the exact compatibility matrix before designing rollout cohorts.
Update checks, activation hooks, and rollback boundaries
At runtime, the package exposes a `Cresc` client and a `ClientOptions` type from the package root. Automatic checking is configured through `checkStrategy`, whose documented values are `onAppStart`, `onAppResume`, `both`, and `null`. Activation behavior is separate. `updateStrategy` can be `alwaysAlert`, `alertUpdateAndIgnoreError`, `silentAndNow`, `silentAndLater`, or `null`, with `alwaysAlert` used in development by default.
The pipeline exposes veto and observation hooks for several stages. `beforeCheckUpdate` and `afterCheckUpdate` cover discovery, while `beforeDownloadUpdate` and `afterDownloadUpdate` cover package transfer and activation decisions. `beforeReload` can veto a `switchVersion` or `restartApp` reload. This gives an application a place to block updates while a transaction is active, but the README does not define every callback signature. Those signatures must be checked in the API documentation before integration.
Rollback depends on distinguishing a healthy startup from a failed one. `autoMarkSuccess` defaults to `true`, and `autoMarkSuccessDelayMs` defaults to `1000`. A `healthCheck` can return `false` to keep crash protection armed. Teams with late-loading critical modules can raise the delay rather than mark success immediately. The trade-off is slower confirmation of health. It also leaves crash protection active longer, which is preferable when startup success is not known at one second.
For a severe JavaScript failure that prevents the app from running normally, the native cold-start path can download a fixed version on the next launch. This is a meaningful boundary: the README says it can address a white screen or launch crash without reinstalling the app or submitting it to the store again. It is still an OTA mechanism for the deployed binary, not a promise that arbitrary native defects can be repaired remotely.
Connecting Cresc and preparing the first OTA release
The README does not give package installation or native-linking commands. It directs new users to the English getting-started documentation at `https://cresc.dev/docs/getting-started`. Consequently, there is no verified `install` command or Expo configuration snippet to reproduce here. The native directories, `react-native-update.podspec`, `react-native.config.js`, and `expo-module.config.json` show that installation has platform-specific parts, but copying an unstated package-manager command would risk omitting required native setup.
After following the getting-started guide and obtaining an app identity from the update service, the first useful client setup can follow the documented TypeScript example. This creates the client with an `appKey` and demonstrates explicit reporting of a caught order failure.
import { Cresc } from 'react-native-update';
const client = new Cresc({ appKey: 'your-app-key' });
try {
await submitOrder();
} catch (error) {
client.captureException(error, {
extra: { screen: 'checkout', retry: 1 },
});
}The example expects `appKey` to identify the application on the update platform. A successful connection should let the SDK obtain update configuration and report events for that app identity. The README does not document a local development server, a simulator-only mode, or a command that publishes a test update, so none is presented here.
Production configuration deserves explicit review. `testChannel` defaults to `true` and makes the client honor `__rnPushyVersionHash` deep links or QR codes. The README instructs production builds to set it to `false`. Teams also need to decide whether native or JavaScript code owns persisted cold-start configuration through `nativeConfigSource`, particularly when migrating a host that calls `configure()` itself.
Staged rollout, health reporting, and error visibility
The hosted service adds controls that sit above client-side patching. The dashboard is documented with version distribution, update success rates, percentage-based staged rollouts, and release health monitoring. These features support a gradual delivery process: start with a limited population, inspect health, and widen the rollout. The README does not document dashboard automation endpoints, permission scopes, retention periods, or service-level commitments, so those points require separate confirmation.
The client sends lifecycle events by default, including download or patch failure, rollback, and successful marking. `disableTelemetry` stops those lifecycle events. JavaScript error reporting is separate and can be disabled with `disableErrorReporting`, which also disables transport for manual `captureException` calls. The documentation states that reporting is best-effort, disabled in development, and disabled when telemetry is disabled.
Error attribution is tied to an OTA release with a known version hash. The client sends uncaught JavaScript errors and manually captured exceptions, and it includes source-mapped stacks according to the project description. The example restricts manual context to bounded scalar values and warns against secrets or personal information. This is a design constraint, not merely an implementation detail. Product code must review any context passed into `captureException` before release.
`client.setOptions(...)` allows runtime changes such as disabling reporting. Reporting also never replaces an existing React Native, Sentry, or Crashlytics global handler. The client exposes `getUpdateMetadata()`, `attachToSentry()`, and `attachToCrashlytics()` for integrations, while `logger` receives SDK events. `throwError` defaults to `false`, although pipeline errors always reach `onError`. These options let an application control failure visibility without changing the package's core activation flow.
Operational limits, alternatives, and maintenance cost
The clearest operational dependency is the hosted Cresc or Pushy service. The default `server` setting uses a preset for main endpoints and HTTPS-only remote endpoint discovery, and the documentation also lists a global service at `cresc.dev` and a China service at `pushy.reactnative.cn`. An organization that forbids hosted update services, requires a different data boundary, or must operate its entire release path internally would need features not established by the README. The existence of open APIs and an MCP server does not by itself prove that the dashboard and delivery infrastructure can be self-hosted.
A real alternative is Microsoft App Center CodePush before its retirement, but the project explicitly presents itself as a replacement because CodePush ended with App Center on March 31, 2025. Another approach is a full-bundle OTA system that always downloads and activates a complete JavaScript bundle instead of applying a Hermes-aware differential patch. That method may simplify patch compatibility, but the README says full-bundle systems commonly send tens of megabytes while this project targets much smaller diffs. The trade-off is greater dependence on differential package compatibility with the app's Hermes output.
The repository is not archived. Its last push was on 2026-10-15, and releases include v10.60.0 on 2026-10-12, v10.59.2 on 2026-10-03, and v10.59.1 on 2026-09-29. This is recent repository activity, but it does not by itself guarantee compatibility with every future React Native release.
Maintenance also includes native compatibility work across three platforms and custom review of the package's `LICENSE`. The repository classifies that license as “Other,” and this review cannot state permissions or restrictions without reading its complete terms. Upgrade planning should account for React Native, Hermes, iOS, Android, and HarmonyOS compatibility rather than assuming JavaScript-only upgrades.
Editorial conclusion
Adopt react-native-update if your React Native applications already use Hermes and your team accepts an OTA service dependency plus the custom LICENSE terms. Do not assume its update policy covers native binary changes, and do not choose it without checking Hermes compatibility, supported React Native versions, rollback behavior, telemetry requirements, and the LICENSE file. Before publishing the first release, verify the documented appKey configuration, update strategy, native configuration ownership, and production handling of testChannel.
Frequently asked questions
Does react-native-update support Hermes and the React Native New Architecture?
Yes. The README states that the pipeline is optimized for Hermes bytecode and that the New Architecture is supported. For Android, it excludes React Native 0.73.0 through 0.76.0 from New Architecture support because of upstream issues.
How does react-native-update recover an OTA update that crashes before JavaScript runs?
A native cold-start check can download a fixed version when JavaScript cannot run normally, such as after a white screen or launch crash. The README says recovery happens on the next launch without reinstalling the app.
Can react-native-update roll out an OTA release to a percentage of users?
Yes. The hosted dashboard supports staged rollouts by percentage, along with version distribution, update success rates, and release health monitoring.
What should be disabled for react-native-update in a production build?
The documented setting is `testChannel: false`. Its default is `true`, which honors `__rnPushyVersionHash` deep links and QR codes for test releases.
Does react-native-update report JavaScript errors automatically?
The documentation says uncaught and manually captured JavaScript errors are reported against the running OTA release by default. Reporting is best-effort and can be disabled with `disableErrorReporting` or `disableTelemetry`.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/reactnativecn-react-native-update)Was this useful?