This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

Expo Updates iconExpo Updates

A library that enables your app to manage remote updates to your application code.

Android
iOS
tvOS
Included in Expo Go
Recommended version:
~56.0.28

expo-updates is a library that enables your app to manage remote updates to your application code. It communicates with the configured remote update service to get information about available updates.

Installation

The expo-updates library can be automatically configured using EAS Update, which is a hosted service that manages and serves updates to your app. To get started with EAS Update, follow the instructions in the Get started guide.

Alternatively, it is also possible to configure the expo-updates library manually in cases where a different remote update service is required or configuration is only specified in native files.

Manual installation, configuration, and custom remote update services
Terminal
- npx expo install expo-updates
- yarn expo install expo-updates
- pnpm expo install expo-updates
- bun expo install expo-updates

If you're installing this library in an existing React Native project or a generic app with manually configured native code, follow these installation instructions.

If using app config for configuration, this library can be configured by setting at least the following app config properties:

The remote service must implement the Expo Updates protocol. EAS Update is one such service, but it is also possible to use this library with a custom server.

Custom Expo Updates Server

Example implementation of a custom server and an app using that server.

Configuration

There are build-time configuration options that control the behavior of the library. For most apps, these configuration values are set in the app config under the updates property.

App config propertyDefaultRequired?iOS plist/dictionary keyAndroid meta-data nameAndroid Map key
updates.enabledtrueEXUpdatesEnabledexpo.modules.updates.ENABLEDenabled
updates.url(none)EXUpdatesURLexpo.modules.updates.EXPO_UPDATE_URLupdateUrl
updates.requestHeaders(none)EXUpdatesRequestHeadersexpo.modules.updates.UPDATES_CONFIGURATION_REQUEST_HEADERS_KEYrequestHeaders
runtimeVersion(none)EXUpdatesRuntimeVersionexpo.modules.updates.EXPO_RUNTIME_VERSIONruntimeVersion
updates.checkAutomaticallyON_LOADEXUpdatesCheckOnLaunchexpo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCHcheckOnLaunch
updates.fallbackToCacheTimeout0EXUpdatesLaunchWaitMsexpo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MSlaunchWaitMs
updates.useEmbeddedUpdatetrueEXUpdatesHasEmbeddedUpdateexpo.modules.updates.HAS_EMBEDDED_UPDATEhasEmbeddedUpdate
updates.codeSigningCertificate(none)EXUpdatesCodeSigningCertificateexpo.modules.updates.CODE_SIGNING_CERTIFICATEcodeSigningCertificate
updates.codeSigningMetadata(none)EXUpdatesCodeSigningMetadataexpo.modules.updates.CODE_SIGNING_METADATAcodeSigningMetadata
updates.assetPatternsToBeBundled(none)N/AN/AN/A
updates.disableAntiBrickingMeasuresfalseEXUpdatesDisableAntiBrickingMeasuresexpo.modules.updates.DISABLE_ANTI_BRICKING_MEASURESdisableAntiBrickingMeasures
updates.enableBsdiffPatchSupporttrueEXUpdatesEnableBsdiffPatchSupportexpo.modules.updates.ENABLE_BSDIFF_PATCH_SUPPORTenableBsdiffPatchSupport

The two core required configuration options are:

These are configured automatically when following the EAS Update Get started guide.

Runtime version

Each time you build a binary for your app it includes the native code and configuration present at the time of the build as well as native configuration, and this unique combination is represented by a string called a runtime version. A remote update targets one runtime version, indicating that only binaries with a matching runtime version can load the remote update.

Manual configuration

The runtime version can be managed manually by setting the string value in the config field.

{ "expo": { "runtimeVersion": "<runtime_version_string>" } }
Automatic configuration using runtime version policies

Runtime version policies derive the runtime version from another piece of information already present in your project. They can be set in the runtimeVersion config field as follows:

{ "expo": { "runtimeVersion": { "policy": "<policy_name>" } } }

Available policy types:

appVersion

The "appVersion" policy is provided for projects with that wish to define their runtime compatibility based on the app version.

For example, in a project that has the following in its app config:

{ "expo": { "runtimeVersion": { "policy": "appVersion" }, "version": "1.0.0", "ios": { "buildNumber": "1" }, "android": { "versionCode": 1 } } }

The "appVersion" policy will set the runtime version to the project's current "version" property. In this case, the runtime version for the Android and iOS builds and any updates would be "1.0.0".

This policy is great for projects that contain custom native code and that update the "version" field after every public release. To submit an app, the app stores require an updated native version number for each submitted build, which makes this policy convenient if you want to be sure that every version installed on user devices has a different runtime version.

When using this policy, you need to manually update "version" field in the app config every time there is a public release, but for Play Store's Internal Test Track and the App Store's TestFlight uploads, you can rely on "autoIncrement" option in eas.json to manage versions for you.

nativeVersion

The "nativeVersion" policy is provided for projects that wish to define their runtime compatibility based on the project's current "version" and "versionCode" (Android) or "buildNumber" (iOS) properties.

For example, in a project that has the following in its app config:

{ "expo": { "runtimeVersion": { "policy": "nativeVersion" }, "version": "1.0.0", "ios": { "buildNumber": "1" }, "android": { "versionCode": 1 } } }

The runtime version for the Android and iOS builds and any updates would be the combination of "[version]([buildNumber|versionCode])", which in this case would be "1.0.0(1)".

This policy is great for projects containing custom native code that update the native version numbers ("buildNumber" for iOS and "versionCode" for Android) for each build. To submit an app, the app stores require an updated native version number for each submitted build, which makes this policy convenient if you want to be sure that every app uploaded to the Play Store's Internal Test Track and the App Store's TestFlight distribution tools has a different runtimeVersion.

It's important to know that this policy requires management of the native version numbers manually between each build.

Also, if you select a different native version between Android and iOS, you'll end up with builds and updates with separate runtime versions.

fingerprint

The "fingerprint" runtime version policy automatically calculates the runtime version for you, including through changes like SDK upgrades or adding custom native code.

{ "expo": { "runtimeVersion": { "policy": "fingerprint" } } }

This policy works for both projects with and without custom native code. It works by using the @expo/fingerprint package to calculate the hash of your project during builds and updates to determine build-update compatibility (also known as the runtime).

Native configuration and overriding

If your project does not use Continuous Native Generation, these configuration values may also be set in your app's native configuration files or overridden during initialization in native code.

Native configuration instructions

On Android, these options are set as meta-data tags in the AndroidManifest.xml file (adjacent to the tags added during installation if auto-setup was used). You can also set or override them at runtime using UpdatesController.overrideConfiguration().

On iOS, these properties are set as keys in the Expo.plist file. You can also set or override them at runtime by calling AppController.overrideConfiguration.

Importing Swift generated headers for use in Objective-C++

If your iOS native code or AppDelegate.mm is written in Objective-C++, you will need to add the following imports to reference methods on EXUpdatesAppController. This is only necessary for overriding configuration at runtime.

#import "ExpoModulesCore-Swift.h" #import "EXUpdatesInterface-Swift.h" #import "EXUpdates-Swift.h"

Usage

By default, expo-updates checks for updates when the app launches. If an update is available, it downloads the update and applies it the next time the app is restarted. You can tune this startup behavior using the checkAutomatically and fallbackToCacheTimeout configuration options above.

The library also provides a variety of constants to inspect the current update and functions to customize update behavior from your application code (after startup). For example, one common alternative usage pattern is to manually check for updates after the app has started instead of doing the default check on launch.

Example: Check for updates manually

You can configure your app to check for updates manually by doing the following steps:

  1. Set the checkAutomatically configuration value to ON_ERROR_RECOVERY or NEVER to disable the library's default launch behavior.

  2. Add the following code to check for available updates, download them, and reload:

    App.js
    import { View, Button } from 'react-native'; import * as Updates from 'expo-updates'; function App() { async function onFetchUpdateAsync() { try { const update = await Updates.checkForUpdateAsync(); if (update.isAvailable) { await Updates.fetchUpdateAsync(); await Updates.reloadAsync(); } } catch (error) { // You can also add an alert() to see the error message in case of an error when fetching updates. alert(`Error fetching latest Expo update: ${error}`); } } return ( <View> <Button title="Fetch update" onPress={onFetchUpdateAsync} /> </View> ); }

Testing

Most of the methods and constants in this library can be used or tested only in release builds. In debug builds, the default behavior is to always load the latest JavaScript from a development server. It is possible to build a debug version of your app with the same updates behavior as a release build. Such an app will not open the latest JavaScript from your development server — it will load published updates just as a release build does. This may be useful for debugging the behavior of your app when it is not connected to a development server.

To test the content of an update in a development build, run eas update and then browse to the update in your development build. Note that this only simulates what an update will look like in your app, and most of the Updates API is unavailable when running in a development build.

To test updates in a release build, you can create a .apk or a simulator build, or make a release build locally with npx expo run:android --variant release and npx expo run:ios --configuration Release (you don't need to submit this build to the store to test). The full Updates API is available in a release build.

To test the content of an update in Expo Go, run eas update and then browse to the update in Expo Go. Note that this only simulates what an update will look like in your app, and most of the Updates API is unavailable when running in Expo Go. Also note that only updates using Expo Go-compatible libraries are supported.

API

import * as Updates from 'expo-updates';

No API data file found, sorry!

Error codes

CodeDescription
ERR_UPDATES_DISABLEDA method call was attempted when the Updates library was disabled, or the application was running in development mode
ERR_UPDATES_RELOADAn error occurred when trying to reload the application and it could not be reloaded. For existing React Native projects, double-check the setup steps for this library to ensure it has been installed correctly and the proper native initialization methods are called.
ERR_UPDATES_CHECKAn unexpected error occurred when trying to check for new updates. Check the error message for more information.
ERR_UPDATES_FETCHAn unexpected error occurred when trying to fetch a new update. Check the error message for more information.
ERR_UPDATES_READ_LOGSAn unexpected error occurred when trying to read log entries. Check the error message for more information.
ERR_NOT_AVAILABLE_IN_DEV_CLIENTA method is not available when running in a development build. A release build should be used to test this method.