Skip to content

Configuration

To point your Expo app to your custom OTA server, update the updates section of your app.json:

{
"expo": {
"updates": {
"url": "https://your-worker-subdomain.workers.dev/update"
},
"runtimeVersion": {
"policy": "appVersion"
},
"extra": {
"eas": {
"projectId": "your-eas-project-id"
}
}
}
}

You must specify which channel the device should listen to (e.g., production, staging, or main). You can pass this via the requestHeaders in your app’s code or configuration.

Expo OTA updates are tied to a runtimeVersion. If the runtimeVersion of the update does not match the runtimeVersion of the native build, the update will be ignored.

  • appVersion policy: The easiest way to manage compatibility. Updates will only be delivered if the app’s native version (e.g., 1.0.0) matches exactly.
  • Fingerprint: Use expo-updates’s fingerprinting for more granular control based on native dependencies.

By default, Expo checks for updates on launch. If an update is found, it’s downloaded in the background and applied on the next launch.

Implementing a Manual “Check for Updates” Button

Section titled “Implementing a Manual “Check for Updates” Button”

You can use the expo-updates JS API to force a check and reload:

import * as Updates from 'expo-updates';
async function onCheckForUpdate() {
const update = await Updates.checkForUpdateAsync();
if (update.isAvailable) {
await Updates.fetchUpdateAsync();
await Updates.reloadAsync();
}
}