CodePush: The Right Way

Burak Erdem
Level Up Coding
Published in
5 min readOct 6, 2022

--

This article is not about installing CodePush or how to use it. You can always refer the documentation at: https://learn.microsoft.com/en-us/appcenter/distribution/codepush/rn-overview

When it comes to picking a mobile cross platform for your next project today, you probably will be narrowed down to either choose React Native or Flutter. I usually have a foot on both camps and try to not to stick to only one, but I must say I have got more sympathy for React Native. And one of the main reason of that is, which I believe it’s the same for many others: CodePush!

Photo by Rob Hampson on Unsplash

For those who don’t know, CodePush allows you to send Hot Updates (or Over The Air Updates, if you prefer) which don’t necessarily need to be reviewed by the App Store or Google Play Store. This is especially useful if you’re working on a project that requires lot of changes in a short time, such as e-commerce apps. You just fix or introduce a new function in your app business then send the update and that’s it. Your users receive it immediately, just as if were a website.

According to the documentation, after installing the library, you just wrap your entry component, which is usually App.js, and you’re good to go. Even it’s sufficient to make it work, you may want to change the way how your users get the updates in order to make your app more user friendly.

But why do we need to change it? Well, actually you don’t have to. If you do the basic installation, people would get updates on next restart and if it’s an urgent update you can always mark it as “immediate” on App Center’s dashboard and users get it, well, immediately.

This instant update however, leads your users to misinterpret your app behaviour since it would restart out of sudden as soon as it gets the update. Through my past projects, users reported back to me this behaviour as a “bug” which isn’t but still I realized that it is something bad for UX so I decided to change it.

First of all, I think users, especially mobile app users, don’t welcome something unexpected. In every interaction or app function, they do expect something familiar that seem meaningful to them. So, first of all, we’re going to add a modal which alerts users that there is an update available so they will be aware what’s going on. CodePush has updateDialog options which you can specify when you wrap component as shown below:

This setting pops up a native alert when update available so your users would know there is an update waiting for them. The title, body and buttons are all in English but updateDialog parameter also takes an object where you can customize those. Here’s a full example in German:

The dialog slightly changes depending on the type of the update. For standart update, you can close the dialog and choose to install it later while the mandatory update leaves you no choice except installing.

Although we informed users about the update by showing a popup, we also need to show some sort of a progress indicator while downloading it. This ensures that we’re actually getting the update or not. There is no built-in progress in CodePush so we need to make it from scratch.

CodePush provides several events about the update phases as well the as the bytes transferred during the update as like this:

Here we have codePushStatusDidChange and codePushStatusDidChange events which basically allows us to achieve what we want. I know it’s a class component and class functions and your App.js is probably a functional component. You can’t mix those two, but you can always use codePush.sync method instead as described here https://learn.microsoft.com/en-us/appcenter/distribution/codepush/rn-api-ref#codepushsync. Please note that some users experienced that statuses provided this way may not work as expected.

Now for the sake of clarity, let’s stick to the class functions and let’s create a separate component only for CodePush. I also want a tiny line progress bar pops up at the bottom of the app, and when downloaded it will read “Downloaded, restarting…” and restarts the app with the update applied. To accomplish this, we have to manually manage the process. Let’s have a look:

That’s lot of code. Let’s break it down;

First we define 2 variables, stat and downloadProgress. The stat variable basically is responsible for every layout changes in our component, including turn on/off our modal. The downloadProgress on the other hand, is necessary for our progress bar. You can display a percentage if you’d like but in my opinion it’s unnecessary if you have a visual representation somehow.

Then we have a basic layout. We have a modal and a wrapper view which I applied Layout Animation from react-native-reanimated for making a shrinking effect for the upcoming text inside.

We’re using 2 of CodePush events, Downloading and Installed, the rest are there just for logging. We also want to restart the app manually, so in CodePush options I changed installModes to be next app restart. One important thing you may have noticed, we need to wrap this component with codePush instead of App.js, thus you have to unwrap your App if you’ve done it previously.

One more thing; CodePush works in development environment as well. and this may not be something you want. If you want to avoid getting updates while working on a simulator or something, you can edit the bottom part as below:

export default codePush({
checkFrequency: __DEV__ ? codePush.CheckFrequency.MANUAL : codePush.CheckFrequency.ON_APP_RESUME,
installMode: codePush.InstallMode.ON_NEXT_RESTART,
mandatoryInstallMode: codePush.InstallMode.ON_NEXT_RESTART,
updateDialog: true,
})(CodePushManager);

Lastly, we need to put the component in App.js, preferably outside of every Provider components like this:

And that’s it! We have a nice preloader for CodePush updates. You can always experiment with different settings and change different update and installation modes to be best suitable for your project.

CodePush provides the fastest way to update the content of your app, as well as fixing the bugs immediately. There are some other related topics you may want to check out like versioning. This is something important and I’m planning to mention about it in my upcoming article. Until then;

Happy coding!

--

--

A technology enthusiast and a senior developer that makes things actually work