Learn how to install and configure expo-updates in bare React Native projects.
The expo-updates
library fetches and manages updates to app JavaScript and assets received from a remote server. It supports EAS Update, a hosted service that serves updates and provides a variety of tools for managing them. It can also be configured to work with a custom server. This guide explains how set it up for use with EAS Update.
If you are creating a new project, we recommend using npx create-expo-app --template bare-minimum
(or yarn create expo-app --template bare-minimum
) because it will handle the following configuration for you automatically. It includes the expo-updates
config plugin, which will handle the installation steps for you.
You may be reading the wrong guide then! To use expo-updates
in a project that uses CNG, refer to the EAS Update "Get started" guide.
The expo
package must be installed and configured: if you created your project with npx react-native init
and do not have any other Expo packages installed, you will need to install Expo modules before proceeding.
To get started, install expo-updates
:
-Â
npx expo install expo-updates
Then, install pods:
-Â
npx pod-install
Once installation is complete, apply the changes from the following diffs to configure expo-updates
in your project.
Modify the expo
section of app.json. (If you originally created your app using npx react-native init
, you will need to add this section.)
The changes below add the updates URL to the Expo configuration.
The example
updates
URL andprojectId
shown below are for use with EAS Update. The EAS CLI sets this URL correctly for the EAS Update service when runningeas update:configure
.
{
"name": "MyApp",
- "displayName": "MyApp"
+ "displayName": "MyApp",
+ "expo": {
+ "name": "MyApp",
+ "slug": "MyApp",
+ "ios": {
+ "bundleIdentifier": "com.MyApp"
+ },
+ "android": {
+ "package": "com.MyApp"
+ },
+ "runtimeVersion": "1.0.0",
+ "updates": {
+ "url": "https://u.expo.dev/[your-project-id]"
+ },
+ "extra": {
+ "eas": {
+ "projectId": "[your-project-id]"
+ }
+ }
+ }
}
Run eas update:configure
to set the updates
URL and projectId
in app.json.
-Â
eas update:configure
If you want to set up a custom server instead, add your URL to updates.url
in app.json.
{
"name": "MyApp",
"displayName": "MyApp",
"expo": {
"name": "MyApp",
...
"updates": {
- "url": "https://u.expo.dev/[your-project-id]"
+ "url": "http://localhost:3000/api/manifest"
}
}
}
Add the file Podfile.properties.json to the ios directory:
{
"expo.jsEngine": "hermes"
}
Modify ios/Podfile to check for the JS engine configuration (JSC or Hermes) in Expo files:
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -2,6 +2,9 @@ require File.join(File.dirname(`node --print "require.resolve('expo/package.json
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
+require 'json'
+podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
+
platform :ios, '13.0'
prepare_react_native_project!
@@ -41,7 +44,7 @@ target 'MyApp' do
# Hermes is now enabled by default. Disable by setting this flag to false.
# Upcoming versions of React Native may rely on get_default_flags(), but
# we make it explicit here to aid in the React Native upgrade process.
- :hermes_enabled => flags[:hermes_enabled],
+ :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
:fabric_enabled => flags[:fabric_enabled],
# Enables Flipper.
#
Add the Supporting directory containing Expo.plist to your project in Xcode with the following content, to match the content in app.json:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EXUpdatesCheckOnLaunch</key>
<string>ALWAYS</string>
<key>EXUpdatesEnabled</key>
<true/>
<key>EXUpdatesLaunchWaitMs</key>
<integer>0</integer>
<key>EXUpdatesRuntimeVersion</key>
<string>1.0.0</string>
<key>EXUpdatesURL</key>
<string>http://localhost:3000/api/manifest</string>
</dict>
</plist>
Modify android/app/build.gradle to check for the JS engine configuration (JSC or Hermes) in Expo files:
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -52,6 +52,11 @@ react {
// hermesFlags = ["-O", "-output-source-map"]
}
+// Override `hermesEnabled` by `expo.jsEngine`
+ext {
+ hermesEnabled = (findProperty('expo.jsEngine') ?: "hermes") == "hermes"
+}
+
/**
* Set this to true to create four separate APKs instead of one,
* one for each native architecture. This is useful if you don't
Modify android/app/src/main/AndroidManifest.xml to add the expo-updates
configuration XML so that it matches the contents of app.json:
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -9,6 +9,11 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme">
+ <meta-data android:name="expo.modules.updates.ENABLED" android:value="true"/>
+ <meta-data android:name="expo.modules.updates.EXPO_RUNTIME_VERSION" android:value="@string/expo_runtime_version"/>
+ <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
+ <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
+ <meta-data android:name="expo.modules.updates.EXPO_UPDATE_URL" android:value="http://localhost:3000/api/manifest"/>
<activity
android:name=".MainActivity"
android:label="@string/app_name"
If using the updates server URL shown above (a custom non-HTTPS update server running on the same machine), you will need to modify android/app/src/main/AndroidManifest.xml as shown below:
<application
android:name=".MainApplication"
android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:allowBackup="false"
android:theme="@style/AppTheme"
+ android:usesCleartextTraffic="true"
>
Add the Expo runtime version string key to android/app/src/main/res/values/strings.xml:
expo-updates
README.expo-updates
with a custom server that implements the Expo Updates protocol; see the custom-expo-updates-server
README.