Ship OTA (Over-The-Air) When in an Emergency
In short
This article discusses the importance of over-the-air (OTA) updates for React Native applications, highlighting how they can expedite critical bug fixes and updates by bypassing the App Store review process. It explores two popular tools, App Center/CodePush and Expo's EAS Update, for implementing OTA updates and emphasizes their significance in delivering rapid improvements to mobile apps.
Originally published in May 2022, updated in March 2024.
Submit critical updates and fixes instantly through OTA
Issue: Traditional ways of updating apps are too slow and you lose your precious time on them.
The traditional model of sending updates on mobile is fundamentally different from the one we know from writing JavaScript applications for other platforms. Unlike the web, mobile deployment is much more complex and comes with better security out-of-the-box. We discuss this topic in greater detail in our article about Continuous Deployment in mobile apps.
What do OTA updates (or lack of them) mean to your business?
Every update, no matter how quickly shipped by your developers, is usually going to wait some time while the App Store and PlayStore teams review your product against their policies and best practices.
This process is particularly challenging in all Apple platforms where apps are often taken down or rejected, because of not following certain policies or meeting the required standard for the user interface. Thankfully, the risk of your app being rejected with React Native is reduced to a minimum as you're working on the JavaScript part of the application. The React Native CoreTeam ensures that all the changes done to the framework have no impact on the success of your application's submission.
As a result, the submission process takes a while. And if you're about to ship a critical update, every minute counts.
Fortunately, with React Native, it is possible to dynamically ship your JavaScript changes directly to your users, skipping the AppStore review process. This technique is often referred to as an over-the-air update. It lets you change the appearance of your application immediately, for all the users, following the technique you have selected.
When critical bugs happen, minutes and hours can be crucial
Don't wait to fix your end users' experience. If your application is not OTA-ready, you risk being left with a critical bug on many devices, for as long as Apple/Google reviews your product and allows it to be distributed. Even though the review times have gotten much better over the years, it is still a good escape hatch to be able to immediately recover from an error that slipped through the testing pipeline into production.
How to implement OTA updates with App Center/CodePush or EAS Update
Solution: Implementing OTA updates with App Center/CodePush or EAS update
As mentioned earlier, React Native is OTA-ready. It means that its architecture and design choices make such updates possible. However, it doesn't ship with the infrastructure to perform such operations. To do so, you will need to integrate a 3rd-party service that carries its infrastructure for doing so.
These are the popular ways to implement OTA into your app:
- CodePush: A service that is part of Microsoft's App Center suite.
- EAS Update: A service that is created by Expo and is part of the EAS suite.
App Center/CodePush
Configuring the native side
To integrate CodePush into your application, please follow the required steps for iOS and Android respectively. We decided to link to the official guides instead of including the steps here as they include additional native code to apply and that is very likely to change in the months to come.
Configuring the JavaScript side
Once you set up the service on the native side, you can use the JavaScript API to enable the updates and define when they should happen. One of the ways that enable fetching updates on the app startup is to use the CodePush wrapper and wrap your main component.
That’s it! If you have performed all the changes on the native side, your application is now OTA-ready. For more advanced use cases, you can also change the default settings on when to check for updates and when to download and apply them. For example, you can force CodePush to check for updates every time the app is brought back to the foreground and install updates on the next resume.
The following diagram code snippet demonstrates such a solution:
Shipping updates to the application
After configuring CodePush on both JavaScript and the native side of React Native, it is time to launch the update and let your new customers enjoy it. We can do this from the command line by using the App Center CLI:
Then we continue with a <rte-code>release<rte-code> command to bundle React Native assets and files and send them to the cloud:
Once these steps are complete, all users running your app will receive the update using the experience you configured in the previous section.
Before publishing a new CodePush release, you will have to create an application in the App Center dashboard. That will give you the <rte-code>ownerName<rte-code> and <rte-code>appName<rte-code> that you’re looking for. As said before, you can either do this via UI by visiting the App Center or by using the App Center CLI.
EAS Update
EAS Update is an EAS service for delivering Over the Air Updates. It provides first-class support for instant updates in React Native applications and is especially user-friendly if you're already using Expo.
It serves updates from the edge with a global CDN and uses modern networking protocols like HTTP/3 for clients that support them. Furthermore, it implements the Expo Updates protocol, which is an open standard specification for instant updates.
Like other Expo products, EAS Update provides a superior Developer Experience, making it a preferred choice for many developers. It also enhances developer workflows with features like:
- Automated Publishing: Integrate with GitHub Actions for automated update publishing.
- Incremental Rollouts: Roll out updates gradually to a selected percentage of users.
- Rollbacks: Ability to roll back any previously published update.
- Asset Selection: Choose which assets to include in an update.
- Custom Update Strategies: Utilize the useUpdates() hook to create tailored update strategies.
Using EAS Update
To use EAS Update in your project, you'll need to install the <rte-code>eas-cli<rte-code> package and log in to your Expo account using <rte-code>eas login<rte-code>.
To get EAS Update working in your project with the bare React Native workflow, you need to set up Expo in your project. See the guide to make that work correctly.
Setting up EAS Update
Start by installing <rte-code>expo-updates<rte-code> library in your project:
<rte-code>npx expo install expo-updates<rte-code>
Next, initialize your project with EAS Update:
<rte-code>eas update:configure<rte-code>
Then, set up the configuration file for builds:
<rte-code>eas build:configure<rte-code>
After running these commands, <rte-code>eas.json<rte-code> is created at the root of your project. Inside it, you will notice that there are two different build profiles ( <rte-code>preview<rte-code> and <rte-code>production<rte-code>), each with a <rte-code>channel<rte-code> property. A <rte-code>channel<rte-code> allows us to point updates at builds for a profile.
Creating a build
Create a build of your app using EAS Build or another tool of your choice. The new build will include the <rte-code>expo-updates<rte-code> native module, which will be responsible for downloading and launching your updates.
You can set up an internal distribution build using the <rte-code>preview<rte-code> build profile and after the build completes, install it on your device or an emulator or simulator. See internal distribution for more information.
Creating an update
After installing the new build on your device, you're ready to send an update to it! Make a small, visible change to the JS of the app.You can also confirm this change by running the development server with <rte-code>npx expo start<rte-code> locally on our machine.
After you've confirmed our changes, let's run the command to create and publish an update with EAS Update:
<rte-code>eas update --branch preview --message “Fixed a bug.”<rte-code>
This command creates an update. Each update contains details about the branch that is linked to the build profile, the commit, and information about platform-specific (Android and iOS) details. See the conceptual overview of how EAS Update works for more information.
Running an update
After this step is completed, all users running our app will receive an update with the changes. By default, <rte-code>expo-updates<rte-code> checks for the updates in the background when the app launches. When testing with an internal distribution, to see the update in the app you'll need to force close and reopen the app up to two times to see the changes.
You can expand on the default functionality and implement your own strategy using the useUpdates() hook from <rte-code>expo-updates<rte-code>, which allows you to:
- Fetch information on available updates
- Fetch information available on currently running updates
- Check for changes manually using <rte-code>Updates.checkForUpdateAsync()<rte-code>
- Download and run updates using <rte-code>Updates.fetchUpdateAsync()<rte-code>
EAS Update can be very useful for deploying changes to production and is equally beneficial during the development phase. It offers a convenient and rapid method for sharing your work with team members.
Benefits of OTA updates
Benefit: Ship critical fixes and some content instantly to users
With OTA updates integrated into your application, you can send your JavaScript updates to all your users in a matter of minutes. This possibility may be crucial for fixing significant bugs or sending instant patches.
For example, it may happen that your backend will stop working and cause a crash at the startup. It may be a mishandled error – you never had a backend failure during the development and forgot to handle such edge cases. You can fix the problem by displaying a fallback message and informing users about the whole thing. While the development will take you around one hour, the actual update and review process can take hours, if not days. With OTA updates set up, you can react to this in minutes without risking that bad UX will affect the majority of users.