Fetches and manages remotely-hosted assets and updates to your app's JS bundle.
npx @tessl/cli install tessl/npm-expo-updates@29.0.0Expo Updates provides comprehensive remote update management for React Native applications, enabling over-the-air updates without requiring app store submissions. It implements the Expo Update protocol for fetching, verifying, and applying remote code updates with built-in security, rollback capabilities, and React integration.
npm install expo-updatesimport * as Updates from "expo-updates";For specific imports:
import {
checkForUpdateAsync,
fetchUpdateAsync,
reloadAsync,
useUpdates,
isEnabled,
updateId
} from "expo-updates";CommonJS:
const Updates = require("expo-updates");
const { checkForUpdateAsync, fetchUpdateAsync, reloadAsync } = require("expo-updates");import * as Updates from "expo-updates";
// Check if updates are enabled
if (Updates.isEnabled) {
// Check for available update
const checkResult = await Updates.checkForUpdateAsync();
if (checkResult.isAvailable) {
// Download the update
const fetchResult = await Updates.fetchUpdateAsync();
if (fetchResult.isNew) {
// Restart with new update
await Updates.reloadAsync();
}
}
}With React hooks:
import { useUpdates } from "expo-updates";
function UpdatesScreen() {
const {
currentlyRunning,
isUpdateAvailable,
isUpdatePending,
isDownloading
} = useUpdates();
useEffect(() => {
if (isUpdatePending) {
// Update downloaded, restart app
Updates.reloadAsync();
}
}, [isUpdatePending]);
return (
<View>
<Text>
{currentlyRunning.isEmbeddedLaunch
? "Running embedded code"
: "Running downloaded update"}
</Text>
{isUpdateAvailable && (
<Button
title="Download Update"
onPress={() => Updates.fetchUpdateAsync()}
/>
)}
{isDownloading && <Text>Downloading...</Text>}
</View>
);
}Expo Updates is built around several key components:
Core update lifecycle functions for checking, downloading, and applying remote updates with full error handling and state tracking.
function checkForUpdateAsync(): Promise<UpdateCheckResult>;
function fetchUpdateAsync(): Promise<UpdateFetchResult>;
function reloadAsync(options?: { reloadScreenOptions?: ReloadScreenOptions }): Promise<void>;Runtime information about the current update state, configuration, and app lifecycle including update IDs, channels, and launch conditions.
const isEnabled: boolean;
const updateId: string | null;
const channel: string | null;
const runtimeVersion: string | null;
const isEmbeddedLaunch: boolean;
const isEmergencyLaunch: boolean;
const emergencyLaunchReason: string | null;
const launchDuration: number | null;
const checkAutomatically: UpdatesCheckAutomaticallyValue | null;
const manifest: Partial<Manifest>;
const createdAt: Date | null;React hooks and utilities for declarative update management with real-time state tracking and automatic UI updates.
function useUpdates(): UseUpdatesReturnType;
interface UseUpdatesReturnType {
currentlyRunning: CurrentlyRunningInfo;
isStartupProcedureRunning: boolean;
isUpdateAvailable: boolean;
isUpdatePending: boolean;
isChecking: boolean;
isDownloading: boolean;
isRestarting: boolean;
restartCount: number;
availableUpdate?: UpdateInfo;
downloadedUpdate?: UpdateInfo;
downloadProgress?: number;
checkError?: Error;
downloadError?: Error;
lastCheckForUpdateTimeSinceRestart?: Date;
}Advanced features for customizing update behavior including extra parameters, request overrides, and developer utilities.
function getExtraParamsAsync(): Promise<Record<string, string>>;
function setExtraParamAsync(key: string, value: string | null | undefined): Promise<void>;
function setUpdateURLAndRequestHeadersOverride(configOverride: { updateUrl: string; requestHeaders: Record<string, string> } | null): void;
function setUpdateRequestHeadersOverride(requestHeaders: Record<string, string> | null): void;Comprehensive logging system for debugging update issues with structured log entries, filtering, and management capabilities.
function readLogEntriesAsync(maxAge?: number): Promise<UpdatesLogEntry[]>;
function clearLogEntriesAsync(): Promise<void>;
interface UpdatesLogEntry {
timestamp: number;
message: string;
code: UpdatesLogEntryCode;
level: UpdatesLogEntryLevel;
updateId?: string;
assetId?: string;
stacktrace?: string[];
}Testing and debugging utilities available in debug builds for development and testing purposes.
function showReloadScreen(options?: { reloadScreenOptions?: ReloadScreenOptions }): Promise<void>;
function hideReloadScreen(): Promise<void>;type Manifest = ExpoUpdatesManifest | EmbeddedManifest;
interface CurrentlyRunningInfo {
updateId?: string;
channel?: string;
createdAt?: Date;
isEmbeddedLaunch: boolean;
isEmergencyLaunch: boolean;
emergencyLaunchReason: string | null;
launchDuration?: number;
manifest?: Partial<Manifest>;
runtimeVersion?: string;
}
enum UpdatesCheckAutomaticallyValue {
ON_LOAD = 'ON_LOAD',
ON_ERROR_RECOVERY = 'ON_ERROR_RECOVERY',
WIFI_ONLY = 'WIFI_ONLY',
NEVER = 'NEVER'
}
enum UpdateInfoType {
NEW = 'new',
ROLLBACK = 'rollback'
}
interface UpdateInfoNew {
type: UpdateInfoType.NEW;
updateId: string;
createdAt: Date;
manifest: Manifest;
}
interface UpdateInfoRollback {
type: UpdateInfoType.ROLLBACK;
updateId: undefined;
createdAt: Date;
manifest: undefined;
}
type UpdateInfo = UpdateInfoNew | UpdateInfoRollback;type UpdateCheckResult = UpdateCheckResultRollBack | UpdateCheckResultAvailable | UpdateCheckResultNotAvailable;
interface UpdateCheckResultAvailable {
isAvailable: true;
manifest: Manifest;
isRollBackToEmbedded: false;
reason: undefined;
}
interface UpdateCheckResultNotAvailable {
isAvailable: false;
manifest: undefined;
isRollBackToEmbedded: false;
reason: UpdateCheckResultNotAvailableReason;
}
type UpdateFetchResult = UpdateFetchResultSuccess | UpdateFetchResultFailure | UpdateFetchResultRollBackToEmbedded;
interface UpdateFetchResultSuccess {
isNew: true;
manifest: Manifest;
isRollBackToEmbedded: false;
}interface ReloadScreenOptions {
backgroundColor?: string;
image?: string | number | ReloadScreenImageSource;
imageResizeMode?: 'contain' | 'cover' | 'center' | 'stretch';
imageFullScreen?: boolean;
fade?: boolean;
spinner?: {
enabled?: boolean;
color?: string;
size?: 'small' | 'medium' | 'large';
};
}
interface ReloadScreenImageSource {
url?: string;
width?: number;
height?: number;
scale?: number;
}The package includes a command-line interface for development and deployment tasks:
npx expo-updates --help
# Available commands:
npx expo-updates codesigning:generate # Generate code signing certificates
npx expo-updates codesigning:configure # Configure code signing
npx expo-updates assets:verify # Verify asset integrity
npx expo-updates fingerprint:generate # Generate runtime fingerprint
npx expo-updates runtimeversion:resolve # Resolve runtime version
npx expo-updates configuration:syncnative # Sync configuration to native