This repo contains a server and client that implement the Expo Updates protocol specification.
Important
This repo exists to provide a basic demonstration of how the protocol might be translated to code. It is not guaranteed to be complete, stable, or performant enough to use as a full-fledged backend for expo-updates. Expo does not provide hands-on technical support for custom expo-updates server implementations, including what is in this repo. Issues within the expo-updates client library itself (independent of server) may be reported at https://github.com/expo/expo/issues/new/choose. Any pull requests that add new features to this repository will likely be closed; instead, feel free to fork the repository to add new features.
Expo provides a set of service named EAS (Expo Application Services), one of which is EAS Update which can host and serve updates for an Expo app using the expo-updates
library.
In some cases more control of how updates are sent to an app may be needed, and one option is to implement a custom updates server that adheres to the specification in order to serve update manifests and assets. This repo contains an example server implementation of the specification and a client app configured to use the example server.
To understand this repo, it's important to understand some terminology around updates:
- Runtime version: Type: String. Runtime version specifies the version of the underlying native code your app is running. You'll want to update the runtime version of an update when it relies on new or changed native code, like when you update the Expo SDK, or add in any native modules into your apps. Failing to update an update's runtime version will cause your end-user's app to crash if the update relies on native code the end-user is not running.
- Platform: Type: "ios" or "android". Specifies which platform to to provide an update.
- Manifest: Described in the protocol. The manifest is an object that describes assets and other details that an Expo app needs to know to load an update.
The flow for creating an update is as follows:
- Configure and build a "release" version of an app, then run it on a simulator or deploy to an app store.
- Run the project locally, make changes, then export the app as an update.
- In the server repo, we'll copy the update made in #2 to the expo-update-server/updates directory, under a corresponding runtime version sub-directory.
- In the "release" app, force close and reopen the app to make a request for an update from the custom update server. The server will return a manifest that matches the requests platform and runtime version.
- Once the "release" app receives the manifest, it will then make requests for each asset, which will also be served from this server.
- Once the app has all the required assets it needs from the server, it will load the update.
Note: The app is configured to load updates from the server running at http://localhost:3000. If you prefer to load them from a different base URL (for example, in an Android emulator):
- Update
.env.local
in the server. - Update
updates.url
inapp.json
and re-run the build steps below.
The example Expo project configured for the server is located in /expo-updates-client.
Run yarn
and yarn ios --configuration Release
.
Run yarn
and then run yarn android --variant release
.
Let's make a change to the project in /expo-updates-client that we'll want to push as an over-the-air update from our custom server to the "release" app. cd
in to /expo-updates-client, then make a change in App.js.
Once you've made a change you're happy with, inside of /expo-updates-server, run yarn expo-publish
. Under the hood, this script runs npx expo export
in the client, copies the exported app to the server, and then copies the Expo config to the server as well.
Now we're ready to run the update server. Run yarn dev
in the server folder of this repo to start the server.
In the simulator running the "release" version of the app, force close the app and re-open it. It should make a request to /api/manifest, then requests to /api/assets. After the app loads, it should show any changes you made locally.
This server was created with NextJS. You can find the API endpoints in pages/api/manifest.js and pages/api/assets.js.
The code signing keys and certificates were generated using https://github.com/expo/code-signing-certificates.