react native expo eas update publish

i have a react native project with expo and eas update i create the first build of the app and deploy it and create also branch and channel and make an update but it dont know if the app is updated if i will download the aab file again it will contain the new updates? becuase i want to add this update to the google play store so i didnt understand how i update this file…

use eas build

Hi @lior98

Assume as follows:

  • You create an app with expo-updates as one of the dependencies
  • You run eas update:configure
  • You build the app
  • You publish it on the App/Play stores
  • Then you just make some small changes to the JavaScript code
  • You then run eas update ... to make the changes available on the same channel that the app was built with

Then those updates should be available to the deployed apps. But the user will need to close the app and open it again. At that point the app will check for an update and download it. The user will then have to close the app again. The next time the user opens the app it will load the updated JavaScript bundle.

So basically if you publish an update the user will have to close and open the app twice before the update is applied.

However, this all assumes that you had expo-updates installed in the app that is published to the stores and that you did not install new dependencies or upgrade the Expo SDK or something like that.

There are more details in the EAS Update documentation.

Hi @wodin,

However, this all assumes that you … did not install new dependencies or upgrade the Expo SDK or something like that.

New dependencies not allowed for EAS Update? (Same expo sdk)

A React Native app (also applies to an Expo app) consists of some native code and some Javascript code, plus some assets. When you run eas build it compiles the native code, bundles the JavaScript and combines them into the app along with the assets.

Some dependencies are pure JavaScript. If you install one of those, then the native part of the app does not need to change, so technically you do not need to rebuild. You can do an OTA update of the JavaScript code into the existing app.

Other dependencies consist of native code and JavaScript. If you install one of these, then the native part of the app must be rebuilt. Otherwise the JavaScript parts will not be able to find the native code they need and the app will crash. This is also why you get a crash if you try to install a native dependency and run the app in Expo Go.

In the past (with expo build:android and expo build:ios), the whole Expo SDK was always built in to your app, so you could always rely on the native parts being available.

One of the problems with this, and one of the biggest complaints from users, is that it resulted in apps that were bloated with things that not everybody needed. e.g. if you didn’t need the face detector, too bad. You still had a large chuck of face detector code+data built into your app. There were also issues with e.g. the Play Store thinking you tracked users, even if you didn’t, because you had code built in that was able to do that.

To avoid these issues, and also to allow you to install other native dependencies without switching to the Bare workflow, EAS Build only includes the things you actually have in dependencies in your package.json. But this means that if you later install e.g. react-native-svg, you will need to rebuild the app.

An unfortunate side effect of this is that you have to be more careful with updates. You can’t just build an app with Expo SDK 48 and later install another dependency from the Expo SDK and expect the updated JavaScript bundle to work. Now you need to make sure that the “runtime version” of your app (basically the native code) has not changed.

So basically, in the past the “runtime version” was just the Expo SDK version. Every app on the same Expo SDK version had the same runtime version. Now you need to define the runtime version in a way that makes the most sense for your app and you cannot just assume that apps with the same Expo SDK version have the same native code.

The answer to your question is “It depends. But unless you are absolutely sure that the dependency is plain JavaScript, you will need to create a new build with a different runtime version or else the update will crash your app.”

See the Runtime versions and updates guide for more details. In particular the " Avoiding crashes with incompatible updates" section.

See also: Runtime Versions

Thanks @wodin this is illuminating.
I am using “runtimeVersion”: { “policy”: “sdkVersion” } - I understand I don’t need to define my own runtimeVersion number in that case.
I am trying to use eas update for trivial hotfixes without dependency changes.
I’m able to deploy my updates to the branch linked with the channel (I can see it here expo.dev/…/deployments) but the updates don’t get downloaded by the app running that’s channel’s build (on TestFlight and on a closed testing track on Google Play).

As the documentation says:

This runtime version policy is perfect if […] the only native changes you make are when upgrading Expo SDKs.

So as long as you only change/upgrade dependencies when you upgrade to a new Expo SDK version, you should be fine.

While troubleshooting this I find it easiest to create a button that calls Updates.checkForUpdateAsync() and Updates.fetchUpdateAsync() and maybe another button to call Updates.reloadAsync(). Then it’s much clearer what’s going on and you don’t have to restart the app twice and hope for the best. You can also add some console.log() calls to log what’s going on.

Thank you @wodin, I added the code you suggested and realized that while using eas update, the updated version - (despite being a staging release on TestFlight, and not a dev release) - mustn’t use any hosted process.env secrets, and instead it should use local keys, as if it was a dev build running on --dev-client. Does that make sense? Attempting to access process.env causes the updated version to crash.