Skip to main content

Implementing Over-the-Air Updates (EAS Update)

1. Configuring EAS Update

Property Value Description
runtimeVersion "1.0.0" Unique identifier for the runtime version of your app
updates.enabled true Enables over-the-air updates for the app
updates.checkAutomatically "ON_LOAD" How often to check for updates: "ON_LOAD", "ON_ERROR", or "NEVER"
updates.fallbackToCacheTimeout 0 Time in milliseconds to wait before falling back to cached version if update fails

Example: eas.json configuration

{
  "cli": {
    "version": "latest"
  },
  "build": {
    "release": {
      "channel": "production"
    }
  },
  "updates": {
    "enabled": true,
    "checkAutomatically": "ON_LOAD",
    "fallbackToCacheTimeout": 0
  }
}
Note: The runtimeVersion must be updated whenever you want to force an update for users.
Warning: Make sure to set updates.enabled to true in production builds to enable OTA updates.

2. Creating Updates

Command Description Notes
eas update Creates a new over-the-air update for your app Must be run from the root of your project
eas update --branch <branch-name> Creates an update for a specific branch Useful for managing different environments (e.g., staging, production)
eas update --message "<message>" Attaches a message to the update Helps with version control and team communication

Example: Creating an update with a message

eas update --message "Bug fix for login screen"
Note: Updates are only available for apps built with EAS Build.
Warning: Ensure that your app's runtime version matches the update's target runtime version to avoid compatibility issues.

3. Creating Update Branch

Property Value Description
branch.name main Name of the branch to create update for
branch.description Production branch for EAS Update Description of the branch
branch.isProduction true Indicates if this is a production branch

Example: Create a new update branch

expo update:branch:create --name 'staging' --description 'Staging environment branch' --isProduction false
Note: Update branches are managed through EAS Build and must be configured in your eas.json file.

4. Setting Update Message

Property Description Values
message Message to display to the user when the update is available string

Example: Setting Update Message

{"message": "A new version of the app is available with bug fixes."}

5. Publishing to Channel

Command Description Notes
eas update --channel <channel-name> Publishes the latest build to a specified channel Must be run from the project root directory
eas update --channel <channel-name> --message "Update message" Publishes with a custom update message Useful for tracking changes in the EAS Console

Example: Publishing to a Channel

eas update --channel production --message "Fixed critical bug in login flow"
Note: Updates are only available to users who have the expo-updates package installed and configured.
Warning: Ensure that the channel name matches the one configured in your app's app.json or app.config.js.
Channel Name Usage Notes
production For live app releases Typically used for production builds
staging For testing before production Useful for QA and internal testing
development For local development and testing Not recommended for production use

6. Using Runtime Version

Property Value Description
expo.runtimeVersion "1.0.0" Defines the runtime version for over-the-air updates
expo.runtimeVersion.policy "sdk-version" Policy for generating runtime version based on SDK version

Example: Setting Runtime Version in app.json

{
  "expo": {
    "name": "MyApp",
    "slug": "my-app",
    "runtimeVersion": "1.0.0"
  }
}
Note: Runtime version must be a string and should follow semantic versioning (e.g., 1.0.0, 2.1.3). It is used to determine which updates are compatible with the current app build.

7. Implementing Update Hooks

Update hooks in Expo allow you to customize the behavior of over-the-air updates. These hooks are functions that are called at specific points during the update lifecycle.

Hook Description Usage
shouldUpdate Called before an update is applied. Allows you to conditionally prevent the update.
export default function shouldUpdate() {
  return true; // or false to prevent update
}
onUpdate Called after an update is successfully applied.
export default function onUpdate() {
  console.log('Update applied');
}
onError Called if an error occurs during the update process.
export default function onError(error) {
  console.error('Update error:', error);
}

Example: Implementing shouldUpdate Hook

export default function shouldUpdate() {
  // Prevent update if app is in foreground
  return false;
}

Example: Implementing onUpdate Hook

export default function onUpdate() {
  // Log update event
  console.log('App updated to new version');
}

Example: Implementing onError Hook

export default function onError(error) {
  // Send error to crash reporting service
  console.error('Update failed:', error);
}

8. Checking for Updates

Method Description Return Type Notes
Updates.checkForUpdate() Checks if there is an available update Promise<UpdateInfo> Returns update info if available, otherwise null
Updates.isUpdateAvailable() Checks if an update is available Promise<boolean> Simple boolean check for update availability

Example: Checking for Updates

import * as Updates from 'expo-updates';

const checkForUpdate = async () => {
  const updateInfo = await Updates.checkForUpdate();
  if (updateInfo.isAvailable) {
    console.log('Update available:', updateInfo.updateUrl);
  } else {
    console.log('No update available');
  }
};

checkForUpdate();

Example: Simple Update Check

import * as Updates from 'expo-updates';

const isUpdateAvailable = async () => {
  const isAvailable = await Updates.isUpdateAvailable();
  if (isAvailable) {
    console.log('An update is ready to install');
  } else {
    console.log('No update available');
  }
};

isUpdateAvailable();
Note: Updates are only checked when the app is running in a release build. In development, updates will not be fetched.

9. Fetching Updates

Property Description Default
expo-updates Module for managing over-the-air updates n/a
updateUrl URL to fetch update manifest from From EAS Build config
shouldRollBack Whether to rollback to previous version if update fails false

Example: Fetching Updates

import * as Updates from 'expo-updates';

async function fetchAndApplyUpdate() {
  try {
    const update = await Updates.checkForUpdateAsync();
    if (update.isAvailable) {
      await Updates.fetchUpdateAsync();
      await Updates.reloadAsync();
    }
  } catch (error) {
    console.error('Failed to fetch update:', error);
  }
}
Note: Updates are only fetched when the app is running in a release build.
Warning: Ensure that your update URL is correctly configured in EAS Build settings.

10. Reloading App

Method Description Notes
reload() Triggers a full app reload from the server Useful for applying over-the-air updates
reloadAsync() Asynchronously reloads the app Returns a promise that resolves when reload completes

Example: Reloading App

import { reload } from 'expo-updates';

reload();
Note: The reload() function will only work if the app is running in an environment that supports over-the-air updates, such as EAS Update.

11. Rolling Back Updates

Option Values Notes
eas update:rollback eas update:rollback Command to roll back to a previous update
--to <update-id> Roll back to a specific update ID
--platform android, ios Target platform for rollback

Example: Rollback to a specific update

eas update:rollback --to <update-id> --platform android
Note: Ensure the update ID corresponds to a valid previous release in your deployment history.
Warning: Rolling back updates may cause inconsistencies if the app's codebase has changed significantly since the rollback point.

12. Viewing Update History

Field Description Value
updateId Unique identifier for the update 12345678-1234-1234-1234-123456789012
runtimeVersion Runtime version of the update 1.0.0
branch Branch name the update was published to main
createdAt Timestamp when the update was created 2025-04-01T10:00:00Z
message Release notes or message for the update Fixed critical bug in login flow

Example: Fetching Update History via EAS CLI

eas update:list --project-id <PROJECT_ID>

Example: Fetching Update History via EAS REST API

const response = await fetch(
  'https://api.expo.dev/v2/projects/<PROJECT_ID>/updates',
  {
    headers: { 'Authorization': 'Bearer <ACCESS_TOKEN>' }
  }
);

Was this article helpful?