If you land here on this article, you’re probably aware that MS AppCenter is nearing end of life (in March ‘24). AppCenter never was the best CI/CD solution, so most mobile developers don’t even care. But AppCenter does have 1 feature especially interesting to React Native developers: CodePush! CodePush allows you to update the JS bundle of a mobile application, without having to go through the iOS and Play store review process. Super useful in case of crucial bugfixes, since CodePush allows you to deploy a fix in mere minutes.
CodePush always has been free of cost, which was kind of crazy if you think about it. The sad thing is, MS is completely stopping the service (except if you’re on Azure). I would’ve gladly paid for it, but even that is not option. Currently the only alternative is offered by Expo, but the cost of 100$ per month more than I am willing to pay. One of my apps doesn’t generate any revenue at all, so having to pay 100$ every month is simply too high of a cost.
Codepush demystified
Codepush is no rocket science, on a high level perspective it’s pretty easy to understand what’s going on.
Step 1: initiate update process
The react-native-code-push library is a native module, so it contains both JS code and native code.
- The native layer initiates the process by calling checkForUpdate
- The implementation for this function lives in native code and roughly goes through these steps:
- Get the currently active bundle name (contains metadata like version and time)
- Send a request to the backend with the metadata
- Inform JS layer about the status
Step 2: fetch and install updates
When an update is available Codepush requests a signed download url from the backend. The native layer can now download the file, unzip it (since the bundle also contains some static files), and write it to the file system.
Next it’s time to clean up: zip files and bundles for previous app version aren’t kept on device.
Step 3: swap current bundle and reset the JS layer
Now Codepush sets the new bundle on the bridge (Codepush has no support for the new architecture as of now), and restarts the JS layer.
Other features
The steps above are a simplified version of what’s going on, and Codepush also supports more fine grained configuration. For example you can also download the bundle in the background and only install it on next app startup.
Moving on
I decided to build my own solution, since the requirements for a minimal implementation aren’t too bad:
- Native module
React-native-code-push is open source, so a lot of features can be extracted. I decided to only support the new architecture for now, as my app moved away from the old architecture. - Cloud storage
Most apps already have some cloud solution for images or other static files - Backend
A basic setup only requires 1 endpoint that checks for updates and returns a presigned read url if an update is available
I didn’t need a dashboard, but am contemplating building one to provide my solution as a service. I’ll write a next article soon with some implementation details.