One production app moved to Revopush Diff Updates on June 7. Before that, the team shipped fewer OTA updates, but still had days with around 1-2 TB of egress. After the migration, egress went down. Downloads went up. The team also shipped OTA releases more often.

A recent release from the same app shows the size difference: the full OTA package was 18.7 MiB. The generated JavaScript patches were 117.26 KiB, 586.94 KiB, and 611.49 KiB.
OTA updates should make React Native releases faster. If every update still ships a full JavaScript bundle, a small fix can become a large mobile download.
A 100 KB patch has a better chance of reaching users than a 19 MB bundle on slow, unstable, or metered mobile networks.
The numbers from one recent release:
| Payload | Size |
|---|---|
| Full OTA package | 18.7 MiB |
| Generated JS patch | 117.26 KiB |
| Generated JS patch | 586.94 KiB |
| Generated JS patch | 611.49 KiB |
The largest patch in that set is still about 31x smaller than the full OTA package. The smallest patch is more than 160x smaller.
The exact reduction depends on what changed in the release. The useful part is that the download no longer tracks the full bundle size for every JavaScript change.
Large OTA bundles fail at the edges: weak networks, users closing the app mid-download, background downloads losing to mobile data limits. They also make small fixes feel expensive when egress starts to hurt.
With patches measured in hundreds of kilobytes instead of tens of megabytes, the team could ship small fixes without treating each OTA as a bandwidth event.
In this customer data, fewer bytes transferred and more downloads completed. The team also shipped OTA releases more often.
A common limitation in diff-based update systems is the baseline problem. Teams may need to ship a full OTA update first, then only get smaller diffs later.
Revopush 2.0 avoids that workflow for supported releases by using the native app binary as the base release. The base release is a snapshot of the JavaScript bundle and assets shipped with the IPA, APK, or AAB. Future OTA updates can be generated as patches against that baseline.
The first OTA on top of a native release can already be a diff. Teams moving from a CodePush-style setup do not need to push one full OTA baseline first.
Start by creating a base release from the native binary:
revopush release-native <APPLICATION_NAME> ios ./path_to_ipa/app.ipa
revopush release-native <APPLICATION_NAME> android ./path_to_apk/app.apkThen publish regular JavaScript and asset updates with the Revopush CLI. For React Native apps, that usually means release-react. For Expo apps, use release-expo.
revopush release-react <APPLICATION_NAME> ios -d <DEPLOYMENT_NAME>
revopush release-react <APPLICATION_NAME> android -d <DEPLOYMENT_NAME>revopush release-expo <APPLICATION_NAME> ios -d <DEPLOYMENT_NAME>
revopush release-expo <APPLICATION_NAME> android -d <DEPLOYMENT_NAME>Revopush compares the new update with the base release and generates patches for files that already exist in the store build and on users' devices.
Revopush Diff Updates now work with React Native 0.83 and Expo SDK 55 projects.
The Revopush 2.0 user guide lists SDK support for React Native 0.83. The Expo integration guide lists Expo SDK 55 support through the Revopush SDK and Expo config plugin.
For Expo projects, the integration still requires native configuration, so it does not run inside Expo Go. Use a native build generated through prebuild, EAS Build, or your own native build pipeline.
The size drop is most visible in apps with large JavaScript bundles, asset-heavy screens, frequent hotfixes, users on weak networks, or release teams trying to reduce OTA egress.
Expo SDK 55 projects can use Revopush Diff Updates when OTA delivery needs to sit outside a purely EAS Update workflow. A 117 KiB patch is easier to ship than an 18.7 MiB bundle, and it is easier for users to download.