Expo OTA Updates: Secure JavaScript Delivery Without App Store Resubmission
Expo OTA updates allow developers to push JavaScript bundle changes instantly, bypassing the traditional app-store review cycle. Learn how it works, how to enable/disable it, and the trade-offs involved.
02 Feb 2026, 20:09 UTC

Publishing app updates through app stores can be slow and cumbersome, especially when only JavaScript changes are needed. Expo’s over-the-air (OTA) updates solve this by allowing developers to push JavaScript bundle changes instantly, bypassing the traditional app-store review cycle. The key takeaway is that Expo OTA updates enable rapid JavaScript updates while maintaining security through signed manifests and a fallback mechanism for failed updates.
How Expo OTA Updates Work
Expo OTA updates work by delivering a signed manifest that references a cached JavaScript bundle. The update process involves the following steps:
- Publishing: The developer runs
expo publish, which generates a new JavaScript bundle and a signed manifest. The manifest includes a URL to the new bundle and a signature generated with the Expo account’s private key. - Downloading: When the app starts, it checks for a new manifest. If one is available, the app downloads the new bundle and verifies the manifest’s signature.
- Applying: If the signature is valid, the app applies the new bundle. If the update fails, the app reverts to the last known good bundle.
The signing mechanism ensures that only trusted updates are applied, preventing tampering. The fallback strategy preserves the user experience by reverting to the last known good bundle if the update fails.
Enabling and Disabling OTA Updates
Developers can configure OTA updates in their Expo project. The expo-updates package is included by default in managed workflow projects. For bare workflow projects, developers can omit the OTA runtime if they do not need OTA updates.
To enable OTA updates, ensure the expo-updates package is installed and configured in the app.json or app.config.js file:
{
"expo": {
"updates": {
"enabled": true,
"fallbackToCacheTimeout": 0
}
}
}
To disable OTA updates, set "enabled": false in the configuration:
{
"expo": {
"updates": {
"enabled": false
}
}
}
Disabling OTA updates means that all changes, including JavaScript changes, will require a new app-store submission.
Practical Example: Publishing and Verifying an OTA Update
Let’s walk through a practical example of publishing and verifying an OTA update:
- Publish the Update: Run
expo publishin the project directory. This command generates a new JavaScript bundle and a signed manifest. - Install the App: Install the app on a device. The app should fetch the new bundle and display the updated UI.
- Inspect the Manifest: Inspect the
expo-updatesmanifest in the device’s app data folder to confirm the signed manifest URL matches the published version. - Enable Debug Mode: Enable
expo-updatesdebug mode in the app to log the update download and installation process, verifying that the runtime applies the new bundle correctly.
This example demonstrates how to publish and verify an OTA update, ensuring that the new bundle is correctly applied and the user experience is preserved.
Trade-offs and Limitations
While Expo OTA updates offer significant benefits, there are trade-offs and limitations to consider:
- Native Module Changes: OTA updates cannot modify native modules. Any change to native code still requires a new app-store submission.
- Security Risks: The signing key must be kept secure. If compromised, an attacker could push malicious code to all users.
- Bundle Size: Large JavaScript bundles can still cause noticeable download times. Developers should split code into smaller chunks where possible.
To mitigate these risks, developers should ensure the signing key is secure, monitor bundle sizes, and plan for native module changes that require app-store submissions.
Conclusion
Expo OTA updates provide a powerful way to push JavaScript bundle changes without app-store resubmission. By understanding how OTA updates work, enabling and disabling them as needed, and considering the trade-offs and limitations, developers can leverage this feature to deliver rapid updates while maintaining security and user experience.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.