or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-config.mdapp-state-config.mdindex.mdlogging-debugging.mdreact-integration.mdupdate-management.md
tile.json

app-state-config.mddocs/

App State and Configuration

Runtime information about the current update state, configuration, and app lifecycle including update IDs, channels, launch conditions, and manifest data.

Capabilities

Update State Constants

Core constants providing information about the current update state and configuration.

/**
 * Whether expo-updates is enabled. May be false in various cases including:
 * - enabled set to false in configuration
 * - missing or invalid URL in configuration  
 * - missing runtime version or SDK version in configuration
 * - error accessing storage on device during initialization
 * When false, the embedded update is loaded.
 */
const isEnabled: boolean;

/**
 * The UUID that uniquely identifies the currently running update.
 * The UUID is represented in its canonical string form and will always use lowercase letters.
 * This value is null when running in a local development environment or any other 
 * environment where expo-updates is disabled.
 * @example "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
 */
const updateId: string | null;

/**
 * The channel name of the current build, if configured for use with EAS Update. null otherwise.
 * Expo Go and development builds are not set to a specific channel and can run any updates 
 * compatible with their native runtime. Therefore, this value will always be null when 
 * running an update on Expo Go or a development build.
 */
const channel: string | null;

/**
 * The runtime version of the current build.
 */
const runtimeVersion: string | null;

/**
 * Determines if and when expo-updates checks for and downloads updates automatically on startup.
 */
const checkAutomatically: UpdatesCheckAutomaticallyValue | null;

enum UpdatesCheckAutomaticallyValue {
  /** Checks for updates whenever the app is loaded. This is the default setting. */
  ON_LOAD = 'ON_LOAD',
  /** Only checks for updates when the app starts up after an error recovery. */
  ON_ERROR_RECOVERY = 'ON_ERROR_RECOVERY',
  /** Only checks for updates when the app starts and has a Wi-Fi connection. */
  WIFI_ONLY = 'WIFI_ONLY',
  /** Automatic update checks are off, and update checks must be done through the JS API. */
  NEVER = 'NEVER'
}

Usage Examples:

import * as Updates from "expo-updates";

// Check if updates are enabled
if (Updates.isEnabled) {
  console.log("Updates are enabled");
  console.log("Current update ID:", Updates.updateId);
  console.log("Channel:", Updates.channel);
  console.log("Runtime version:", Updates.runtimeVersion);
  console.log("Check automatically:", Updates.checkAutomatically);
} else {
  console.log("Updates are disabled - running embedded code");
}

// Conditional behavior based on update state
function getUpdateInfo() {
  return {
    hasUpdates: Updates.isEnabled,
    currentVersion: Updates.updateId || 'embedded',
    channel: Updates.channel || 'development',
    autoCheck: Updates.checkAutomatically || 'unknown'
  };
}

Launch State Constants

Information about how the app was launched and its current execution state.

/**
 * This will be true if the currently running update is the one embedded in the build,
 * and not one downloaded from the updates server.
 */
const isEmbeddedLaunch: boolean;

/**
 * expo-updates does its very best to always launch monotonically newer versions of your app so
 * you don't need to worry about backwards compatibility when you put out an update. In very rare
 * cases, it's possible that expo-updates may need to fall back to the update that's embedded in
 * the app binary, even after newer updates have been downloaded and run (an "emergency launch").
 * This boolean will be true if the app is launching under this fallback mechanism and false
 * otherwise. If you are concerned about backwards compatibility of future updates to your app, you
 * can use this constant to provide special behavior for this rare case.
 */
const isEmergencyLaunch: boolean;

/**
 * If isEmergencyLaunch is set to true, this will contain a string error message describing
 * what failed during initialization.
 */
const emergencyLaunchReason: string | null;

/**
 * Number of milliseconds it took to launch.
 */
const launchDuration: number;

Usage Examples:

import * as Updates from "expo-updates";

// Check launch conditions
if (Updates.isEmbeddedLaunch) {
  console.log("Running embedded code from app bundle");
} else {
  console.log("Running downloaded update");
}

if (Updates.isEmergencyLaunch) {
  console.warn("Emergency launch detected!");
  console.warn("Reason:", Updates.emergencyLaunchReason);
  // Handle emergency state - maybe show fallback UI
  showEmergencyFallbackUI(Updates.emergencyLaunchReason);
}

console.log(`App launch took ${Updates.launchDuration}ms`);

// Performance monitoring
function logLaunchMetrics() {
  const metrics = {
    launchDuration: Updates.launchDuration,
    isEmbedded: Updates.isEmbeddedLaunch,
    isEmergency: Updates.isEmergencyLaunch,
    updateId: Updates.updateId
  };
  
  // Send to analytics service
  analytics.track('app_launch', metrics);
}

Manifest and Creation Time

Information about the currently running update's manifest and creation time.

/**
 * If expo-updates is enabled, this is the manifest (or classic manifest)
 * object for the update that's currently running.
 * In development mode, or any other environment in which expo-updates is disabled, 
 * this object is empty.
 */
const manifest: Partial<Manifest>;

/**
 * If expo-updates is enabled, this is a Date object representing the creation time 
 * of the update that's currently running (whether it was embedded or downloaded at runtime).
 * In development mode, or any other environment in which expo-updates is disabled, 
 * this value is null.
 */
const createdAt: Date | null;

type Manifest = ExpoUpdatesManifest | EmbeddedManifest;

Usage Examples:

import * as Updates from "expo-updates";

// Access manifest data
if (Updates.manifest && Object.keys(Updates.manifest).length > 0) {
  console.log("Current manifest:", Updates.manifest);
  
  // Access specific manifest properties
  if ('id' in Updates.manifest) {
    console.log("Manifest ID:", Updates.manifest.id);
  }
  
  if ('metadata' in Updates.manifest) {
    console.log("Metadata:", Updates.manifest.metadata);
  }
} else {
  console.log("No manifest available (development mode)");
}

// Check update creation time
if (Updates.createdAt) {
  console.log("Update created at:", Updates.createdAt.toISOString());
  console.log("Update age:", Date.now() - Updates.createdAt.getTime(), "ms");
  
  // Show update age in UI
  const ageInHours = (Date.now() - Updates.createdAt.getTime()) / (1000 * 60 * 60);
  if (ageInHours > 24) {
    console.log(`Update is ${Math.floor(ageInHours / 24)} days old`);
  }
} else {
  console.log("No creation time available (development mode)");
}

// Create update summary
function getCurrentUpdateSummary() {
  return {
    id: Updates.updateId,
    isEmbedded: Updates.isEmbeddedLaunch,
    createdAt: Updates.createdAt?.toISOString(),
    manifest: Updates.manifest,
    channel: Updates.channel,
    runtimeVersion: Updates.runtimeVersion
  };
}

Hidden/Internal Constants

Constants that are part of the API but not publicly documented, typically used internally or for testing.

/**
 * @hidden
 * Local assets mapping
 */
const localAssets: Record<string, string>;

/**
 * @hidden  
 * Whether using embedded assets
 */
const isUsingEmbeddedAssets: boolean;

Usage Examples:

// These are typically not used in application code
// but may be useful for debugging or internal tooling

console.log("Local assets:", Updates.localAssets);
console.log("Using embedded assets:", Updates.isUsingEmbeddedAssets);

Complete State Check Pattern

Common pattern for checking all update state information:

import * as Updates from "expo-updates";

function getCompleteUpdateState() {
  const state = {
    // Core state
    enabled: Updates.isEnabled,
    updateId: Updates.updateId,
    channel: Updates.channel,
    runtimeVersion: Updates.runtimeVersion,
    
    // Launch state
    isEmbedded: Updates.isEmbeddedLaunch,
    isEmergency: Updates.isEmergencyLaunch,
    emergencyReason: Updates.emergencyLaunchReason,
    launchDuration: Updates.launchDuration,
    
    // Update metadata
    manifest: Updates.manifest,
    createdAt: Updates.createdAt,
    
    // Configuration
    checkAutomatically: Updates.checkAutomatically
  };
  
  return state;
}

// Use in React component
function UpdateStateDisplay() {
  const state = getCompleteUpdateState();
  
  return (
    <View>
      <Text>Updates Enabled: {state.enabled ? 'Yes' : 'No'}</Text>
      <Text>Update ID: {state.updateId || 'None'}</Text>
      <Text>Channel: {state.channel || 'None'}</Text>
      <Text>Launch Type: {state.isEmbedded ? 'Embedded' : 'Downloaded'}</Text>
      {state.isEmergency && (
        <Text style={{color: 'red'}}>
          Emergency Launch: {state.emergencyReason}
        </Text>
      )}
      {state.createdAt && (
        <Text>Created: {state.createdAt.toLocaleDateString()}</Text>
      )}
    </View>
  );
}