Fetches and manages remotely-hosted assets and updates to your app's JS bundle.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Expo 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