xref: /expo/docs/pages/bare/installing-updates.mdx (revision cedf99eb)
1---
2title: Add expo-updates to an existing project
3description: Learn how to add expo-updates to an existing React Native project.
4---
5
6import { DiffBlock, Terminal } from '~/ui/components/Snippet';
7import { Collapsible } from '~/ui/components/Collapsible';
8
9The `expo-updates` library fetches and manages updates received from a remote server. It supports [EAS Update](/eas-update/introduction), a hosted service that serves updates for projects using the `expo-updates` library.
10
11> 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`) instead of `npx react-native init` because it will handle the following configuration for you automatically. It includes the `expo-updates` [config plugin](/guides/config-plugins), which will handle the following steps for you.
12
13## Installation
14
15The `expo-updates` library requires that your project already has [Expo modules configured](/bare/installing-expo-modules). Be sure to install it before continuing.
16
17To get started, install `expo-updates`:
18
19<Terminal cmd={['$ npx expo install expo-updates']} />
20
21Then, install pods:
22
23<Terminal cmd={['$ npx pod-install']} />
24
25Once installation is complete, apply the changes from the following diffs to configure `expo-updates` in your project.
26
27## Configuration in JavaScript and JSON
28
29Modify the `expo` section of **app.json**. (If you originally created your app using `npx react-native init`, you will need to add this section.)
30The changes below add the updates URL to the Expo configuration.
31
32> 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.
33
34```diff app.json
35 {
36   "name": "MyApp",
37-  "displayName": "MyApp"
38+  "displayName": "MyApp",
39+  "expo": {
40+    "name": "MyApp",
41+    "slug": "MyApp",
42+    "ios": {
43+      "bundleIdentifier": "com.MyApp"
44+    },
45+    "android": {
46+      "package": "com.MyApp"
47+    },
48+    "runtimeVersion": "1.0.0",
49+    "updates": {
50+      "url": "http://localhost:3000/api/manifest"
51+    }
52+  }
53 }
54```
55
56
57## Configuration for iOS
58
59Add the file **Podfile.properties.json** to the **ios** directory:
60
61```json ios/Podfile.properties.json
62{
63  "expo.jsEngine": "hermes"
64}
65```
66
67Modify **ios/Podfile** to check for the JS engine configuration (JSC or Hermes) in Expo files:
68
69```diff ios/Podfile
70--- a/ios/Podfile
71+++ b/ios/Podfile
72@@ -2,6 +2,9 @@ require File.join(File.dirname(`node --print "require.resolve('expo/package.json
73 require_relative '../node_modules/react-native/scripts/react_native_pods'
74 require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
75
76+require 'json'
77+podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
78+
79 platform :ios, '13.0'
80 prepare_react_native_project!
81
82@@ -41,7 +44,7 @@ target 'MyApp' do
83     # Hermes is now enabled by default. Disable by setting this flag to false.
84     # Upcoming versions of React Native may rely on get_default_flags(), but
85     # we make it explicit here to aid in the React Native upgrade process.
86-    :hermes_enabled => flags[:hermes_enabled],
87+    :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes',
88     :fabric_enabled => flags[:fabric_enabled],
89     # Enables Flipper.
90     #
91
92```
93Add the **Supporting** directory containing **Expo.plist** to your project in Xcode with the following content, to match the content in **app.json**:
94
95```xml Expo.plist
96<?xml version="1.0" encoding="UTF-8"?>
97<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
98<plist version="1.0">
99  <dict>
100    <key>EXUpdatesCheckOnLaunch</key>
101    <string>ALWAYS</string>
102    <key>EXUpdatesEnabled</key>
103    <true/>
104    <key>EXUpdatesLaunchWaitMs</key>
105    <integer>0</integer>
106    <key>EXUpdatesRuntimeVersion</key>
107    <string>1.0.0</string>
108    <key>EXUpdatesURL</key>
109    <string>http://localhost:3000/api/manifest</string>
110  </dict>
111</plist>
112```
113
114## Configuration for Android
115
116Modify **android/app/build.gradle** to check for the JS engine configuration (JSC or Hermes) in Expo files:
117
118```diff android/app/build.gradle
119--- a/android/app/build.gradle
120+++ b/android/app/build.gradle
121@@ -52,6 +52,11 @@ react {
122     // hermesFlags = ["-O", "-output-source-map"]
123 }
124
125+// Override `hermesEnabled` by `expo.jsEngine`
126+ext {
127+  hermesEnabled = (findProperty('expo.jsEngine') ?: "hermes") == "hermes"
128+}
129+
130 /**
131  * Set this to true to create four separate APKs instead of one,
132  * one for each native architecture. This is useful if you don't
133```
134
135Modify **android/app/src/main/AndroidManifest.xml** to add the `expo-updates` configuration XML so that it matches the contents of **app.json**:
136
137```diff android/app/src/main/AndroidManifest.xml
138--- a/android/app/src/main/AndroidManifest.xml
139+++ b/android/app/src/main/AndroidManifest.xml
140@@ -9,6 +9,11 @@
141       android:roundIcon="@mipmap/ic_launcher_round"
142       android:allowBackup="false"
143       android:theme="@style/AppTheme">
144+      <meta-data android:name="expo.modules.updates.ENABLED" android:value="true"/>
145+      <meta-data android:name="expo.modules.updates.EXPO_RUNTIME_VERSION" android:value="@string/expo_runtime_version"/>
146+      <meta-data android:name="expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH" android:value="ALWAYS"/>
147+      <meta-data android:name="expo.modules.updates.EXPO_UPDATES_LAUNCH_WAIT_MS" android:value="0"/>
148+      <meta-data android:name="expo.modules.updates.EXPO_UPDATE_URL" android:value="http://localhost:3000/api/manifest"/>
149       <activity
150         android:name=".MainActivity"
151         android:label="@string/app_name"
152```
153
154Add the Expo runtime version string key to **android/app/src/main/res/values/strings.xml**:
155
156```diff android/app/src/main/res/values/strings.xml
157--- a/android/app/src/main/res/values/strings.xml
158+++ b/android/app/src/main/res/values/strings.xml
159@@ -1,3 +1,4 @@
160 <resources>
161     <string name="app_name">MyApp</string>
162+    <string name="expo_runtime_version">1.0.0</string>
163 </resources>
164```
165
166## Next Steps
167
168See more information about usage in the [`expo-updates` README](https://github.com/expo/expo/tree/main/packages/expo-updates/README.md).
169
170See [this guide](/eas-update/eas-update-with-local-build/) for trying out EAS Update with a local build.
171
172To start trying out EAS Update with EAS Build, see the [EAS Update "Getting Started" guide](/eas-update/getting-started/).
173
174It is also possible to use `expo-updates` with a custom server that implements the [Expo Updates protocol](/technical-specs/expo-updates-1/); see the [`custom-expo-updates-server` README](https://github.com/expo/custom-expo-updates-server#readme).
175