Learn how to add expo-updates to an existing React Native project.
The expo-updates
library fetches and manages updates received from a remote server. It supports EAS Update, a hosted service that serves updates for projects using the expo-updates
library.
If you are creating a new project, we recommend using
npx create-expo-app --template bare-minimum
(oryarn create expo-app --template bare-minimum
) instead ofnpx react-native init
because it will handle the following configuration for you automatically. It includes theexpo-updates
config plugin, which will handle the following steps for you.
The expo-updates
library requires that your project already has Expo modules configured. Be sure to install it before continuing.
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 URL shown here is for use with a custom update server running on the same machine. When using EAS Update, the EAS CLI will set this URL correctly for the EAS Update service.
{
"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": "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.