new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Expo · EAS · all subjects

eas-update

216 notes in this subject, read out of this brain and free to use. This is page 2 of 4.

Image assets location and viewing

App users will download any new images or other assets when they detect a new update if those assets are not already part of their build. All assets uploaded to EAS servers are in dist/assets. The assets there are hashed with their extensions removed. To see a pretty-printed list of assets, run: npx expo export (or yarn expo export, pnpm expo export, or bun expo export depending on package manager).

Integration time estimate for EAS Update

If using the latest Expo SDK supported React Native version and you are comfortable with React Native integration, integration time is similar to tools like CodePush or Sentry. The most important factor is the React Native version; if upgrading from an older version, integration time depends on app size, complexity, and team experience.

iOS AppDelegate setup for expo-updates (SDK 52)

AppDelegate should extend EXAppDelegateWrapper. Add a shared() static method. Add var updatesController: (any InternalAppControllerInterface)?. Define bundledUrl = Bundle.main.url(forResource: 'main', withExtension: 'jsbundle'). Override bundleUrl() to return updatesController?.launchAssetUrl() if available, else bundledUrl. In didFinishLaunchingWithOptions(), set moduleName = 'App', initialProps = [:], rootViewFactory = createRCTRootViewFactory(), and call AppController.initializeWithoutStarting().

iOS CustomViewController setup for expo-updates (SDK 52)

CustomViewController should implement AppControllerDelegate. In init, set appDelegate.updatesController = AppController.sharedInstance, set AppController.sharedInstance.delegate = self, and call AppController.sharedInstance.start(). Implement appController(_:didStartWithSuccess:) to call createView(). In createView(), obtain rootViewFactory from appDelegate.reactNativeFactory?.rootViewFactory, create the root view using rootViewFactory.view(withModuleName: appDelegate.moduleName, initialProperties: appDelegate.initialProps, launchOptions: appDelegate.launchOptions), and add it to the view controller with proper layout constraints.

CodePush migration guide reference

For developers migrating from CodePush to EAS Update, see the Migrating from CodePush guide at /eas-update/codepush/.

Metro config extends expo/metro-config example

Example metro.config.js that extends expo/metro-config: const { getDefaultConfig } = require('expo/metro-config'); const config = getDefaultConfig(__dirname); module.exports = config;

Custom entry point with registerRootComponent for expo-updates

Import App, import registerRootComponent from 'expo', and call registerRootComponent(App). This registers the component with react-native AppRegistry and performs all required Expo initialization including expo-updates setup.

Custom entry point with AppRegistry and Expo initialization

If keeping an existing entry point with AppRegistry directly, add a call to Expo initialization before registering the app: import 'expo/src/Expo.fx'; before calling AppRegistry.registerComponent. Example: import App from './App'; import 'expo/src/Expo.fx'; import { AppRegistry } from 'react-native'; function getApp() { return <App />; } AppRegistry.registerComponent('App', () => getApp());

Android MainApplication.kt setup for expo-updates

The application class must implement ReactApplication. Override reactHost using ExpoReactHostFactory.getDefaultReactHost() with the application context and PackageList.packages. In onCreate(), call loadReactNative(this) and ApplicationLifecycleDispatcher.onApplicationCreate(this). Also implement onConfigurationChanged() to call ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig).

Android MainActivity.kt setup for expo-updates

The React Native activity must subclass com.facebook.react.ReactActivity. Override getMainComponentName() to return the registered app name (e.g., 'App'). Override createReactActivityDelegate() to return ReactActivityDelegateWrapper wrapping a DefaultReactActivityDelegate. In onCreate(), call super.onCreate(null).

iOS AppDelegate setup for expo-updates (SDK 53 and later)

AppDelegate should extend ExpoAppDelegate. Add a shared() static method to retrieve the app delegate instance. Add a reference to AppController singleton: var updatesController: (any InternalAppControllerInterface)?. Create a CustomReactNativeFactoryDelegate class extending ExpoReactNativeFactoryDelegate that overrides bundleUrl() to return the correct bundle URL from updates if running, or the bundled URL. In didFinishLaunchingWithOptions(), initialize ExpoReactNativeFactory with the custom delegate and call AppController.initializeWithoutStarting().

Three approaches to preview updates: development, preview, and production

Before deploying an update to production, test it in a production-like environment using one of three approaches: previewing updates in development builds, previewing updates in preview builds, or previewing updates in production builds.

Channel surfing allows selecting different updates at runtime

Channel surfing builds a mechanism into preview builds that allows users to select a different update or channel to load. This is useful when the app runtime does not change often and many different updates can be loaded in the same app.

Steps to enable request proxying

To enable request proxying: (1) Create two proxy servers, one for update asset requests and one for update manifest requests, with the specified requirements. (2) Add updateAssetHostOverride and updateManifestHostOverride fields to the cli section of eas.json with your actual proxy server URLs. (3) Run 'eas update:configure' command to apply the changes. (4) Publish an update with 'eas update' to test the proxying. (5) Verify by navigating to the update group on the EAS Update dashboard and clicking 'View Metadata' for one of the platforms.

Incompatible update pitfall: relying on native code not in build

An incompatible update occurs when an update relies on native code that the build it's running on does not support. For example, if a build has runtime version 1.0.0 and an update that depends on a newly installed native library like expo-camera is published without updating the runtimeVersion, the build would think the incoming update is compatible and attempt to load it. Since the update would make calls to code that does not exist inside the build, expo-updates may detect an error and attempt to roll back to the previously working update.

appVersion policy for runtime version

The appVersion policy will increment the runtime version whenever the app version is incremented. However, if you forget to bump the app version when changing the native runtime, then you will have a runtime version mismatch.

Strategies to avoid incompatible updates

Strategies to avoid deploying incompatible updates include: using a runtime version policy that automatically updates the runtime version when native code is updated (such as fingerprint policy), manually incrementing the runtime version whenever installing or updating native code, rolling out the update gradually using rollouts to publish to a small percentage of users first, or manually verifying updates with a smaller group of users by creating a preview build that uses the same runtime but points to a different channel.

Deployments section unavailable without EAS Build

When using EAS Update without EAS Build, the Deployments section on expo.dev will not be available. This bookkeeping and insights feature depends on knowledge of builds and requires using EAS Build to provide grouping of builds by channel and runtime version.

Create channel with eas channel:create command

Use the command 'eas channel:create production' to create a channel named production on the server. Channel names should vary depending on your release process.

EAS Update and Build integration benefits

EAS Update and Build work together to provide an experience greater than the sum of its parts. When creating a build with EAS Build, the service handles bookkeeping for aspects related to updates such as runtime version and channel, and provides insights features that depend on knowledge of builds.

Example: Displaying update status to users

This example shows how to check if an update is embedded or downloaded and display the appropriate status: ```tsx import * as Updates from 'expo-updates'; import { Text } from 'react-native'; export default function UpdateStatus() { return ( <Text> {Updates.isEmbeddedLaunch ? '(Embedded) ❌ You cannot trace this update in the EAS dashboard.' : '(Downloaded) ✅ You can trace this update in the EAS dashboard.'} </Text> ); } ```

Custom domain assignment limit

Each project can have exactly one custom domain, which is assigned to the production deployment.

Access custom domain settings in dashboard

Navigate to the project's Hosting settings at https://expo.dev/accounts/[accountName]/projects/[projectName]/hosting/settings to configure a custom domain.

www subdomain explicit setup

To set up an automatic redirection for only the www subdomain on a custom domain, create a CNAME record on www.<yourdomain> pointing to origin.expo.app.

Wildcard CNAME record routing behavior

A wildcard CNAME record starting with * stands for any subdomain. EAS Hosting will attempt to send requests to the deployment assigned to an alias with a matching subdomain name.

www subdomain redirect behavior

When a www subdomain is set up with a wildcard CNAME record and no alias named www exists, requests to the www subdomain will be redirected to the custom domain with a 308 response and treated as a request to the production deployment.

SSL CNAME record subdomain for subdomains

When setting up a subdomain like anything.example.com, the SSL CNAME record for Domain Control Validation must be created on _acme-challenge.anything.example.com.

Routing A record for apex domains

For apex domains, the dashboard typically recommends an A record pointing to 172.66.0.241 to route the domain at EAS Hosting.

Custom domain is a premium feature

Setting up a custom domain is a premium feature and is not available on the free plan.

Routing CNAME record for subdomains

For subdomains, the dashboard typically recommends a CNAME record pointing to origin.expo.app to route the domain at EAS Hosting.

Alias subdomain CNAME records for subdomains

To set up a subdomain CNAME record for an alias on a subdomain like anything.example.com, create a CNAME record on staging.anything.example.com pointing to origin.expo.app, where staging is the alias name.

Wildcard CNAME record for subdomains

To direct any subdomain request to any alias for a subdomain like anything.example.com, create a wildcard CNAME record on *.anything.example.com pointing to origin.expo.app.

Custom domain always routes to production deployment

After assigning a custom domain to an app, the custom domain will always route to the production deployment.

Supported custom domain types

Both apex domains and subdomains are supported for custom domains. If you own example.com, you can use example.com as an apex domain or anything.example.com as a subdomain.

Zero downtime domain switchover

To achieve zero downtime when switching a domain, add DNS records one by one in the order presented: first the Verification TXT record, then the SSL CNAME record, then the routing record (CNAME or A record). Press Refresh after each step until the UI confirms verification. If downtime is not a concern, all three records can be added simultaneously.

Alias URL format

An alias URL consists of the preview subdomain name, two dashes, the user-defined alias name, and the expo.app domain. For example, if the preview subdomain is 'my-app' and the alias is 'hello', the URL is https://my-app--hello.expo.app/.

Production alias URL format

If the preview subdomain name is 'my-app', the production URL will be https://my-app.expo.app/. This is the production alias.

Preview and production URL format

If the preview subdomain name is 'my-app', the preview URL format is https://my-app--<deployment-id>.expo.app/, and the production URL format is https://my-app.expo.app/.

Aliases are custom URLs for deployments

Aliases are user-defined values used for creating custom URLs for deployments. Aliases are unique per project. If you choose an alias that was already in use, it will get re-assigned to the new deployment. A single deployment can have multiple aliases.

Publishing updates workflow structure

A publish update workflow file contains: name (Publish update), on section with push trigger for all branches ('*'), jobs section with update job. The update job has type: update and params with branch field set to github.ref_name or 'test' as fallback.

expo-updates library

The expo-updates library allows you to programmatically make instant updates to your app's JavaScript available to your production app.

EAS Update for instant updates

EAS Update provides first-class support for instant updates in React Native apps. It serves updates from the edge of a global CDN using modern networking protocols like HTTP/3. It is tailored for developers using EAS Build and can also be used with builds created locally.

Assets not matching patterns must be built into native build

When using asset selection, assets that do not match any file patterns will resolve in the Metro bundler but will not be uploaded to the updates server. You must ensure that assets not included in updates are built into the native build of the app.

Asset selection feature overview

The asset selection feature (experimental, generally available from SDK 52) allows developers to specify that only certain assets should be included in updates. This reduces the number of assets that need to be uploaded to and downloaded from the updates server. The feature works with the EAS Update server or any custom server that complies with the expo-updates protocol.

Asset selection does not affect native binary bundling

Asset selection controls which assets are eligible for over-the-air updates. It does not change which assets are bundled into the native binary, so it does not reduce app startup time.

Verify update assets with npx expo-updates assets:verify command

To verify that an update includes all required app assets, use the command npx expo-updates assets:verify <dir>. This command checks whether all required assets will be included when you publish an update. It requires the app to be built locally or have access to the correct build with the same runtime version. This command is part of expo-updates CLI (version >= 0.24.10), not the Expo CLI or EAS CLI.

npx expo-updates assets:verify command options

The npx expo-updates assets:verify command supports the following options: <dir> (Directory of the Expo project, default is current working directory), -a/--asset-map-path <path> (Path to assetmap.json from npx expo export --dump-assetmap), -e/--exported-manifest-path <path> (Path to metadata.json from npx expo export --dump-assetmap), -b/--build-manifest-path <path> (Path to app.manifest file created by expo-updates in an Expo application build for android or ios), -p/--platform <platform> (Options: android or ios), -h/--help (Usage info).

Assets must be required in JavaScript code for inclusion

After adding assetPatternsToBeBundled configuration, ensure that the assets matching the patterns are required in your JavaScript code for them to be included in updates.

Custom update service escape hatch

As an escape hatch for release processes not supported by EAS Update, you can host your own update service compatible with the Expo Updates Protocol and point your `expo-updates` configuration to that service. The only concepts relevant to update selection at the protocol level are "Runtime Version" and "Platform". Each binary version must always point to a single channel and you cannot dynamically update the channel in EAS Update.

Error recovery in expo-updates prevents bricking apps

The error recovery mechanism in expo-updates is designed to prevent updates from bricking your app by ensuring the app has the opportunity to download a new update and fix itself. It is not a full safety net and users may still see crashes, but it helps avoid situations where a broken update makes the app unusable until reinstalled.

Error recovery when content has appeared: 5 second check window

If an error is caught after the content appeared event has fired, a 5 second timer starts and the app checks for a new update and downloads it if available (unless EXUpdatesCheckOnLaunch/expo.modules.updates.EXPO_UPDATES_CHECK_ON_LAUNCH is set to NEVER). If no new update is found, the update finishes downloading, or the timer runs out, the app throws the original error and crashes. Any new update downloaded will launch when the user next opens the app.

Content appeared event determines error recovery rollback behavior

The error recovery behavior depends on whether React Native has fired the native 'content appeared' event (ReactMarkerConstants.CONTENT_APPEARED on Android or RCTContentDidAppearNotification on iOS), which occurs approximately when the app's first view renders. Before this event, expo-updates may automatically roll back to an older update. After this event, expo-updates will only fix forward without rolling back, because rolling back becomes dangerous if the new update has modified persistent state non-backwards-compatibly.

Error recovery when content has not appeared: automatic retry and rollback

If an error is caught before the content appeared event fires and this is the first launch of the current update on the device, the update is marked failed locally and will not launch again. A 5 second timer starts and the app checks for a new update (unless EXUpdatesCheckOnLaunch is NEVER). If a new update downloads before the timer expires, the app immediately reloads with the new update. If this new update also throws a fatal error, no new update exists, or the timer runs out, the app tries to reload by rolling back to the most recently successfully launched older update. If rollback fails or no older update is available, the app throws the original error and crashes.

Error recovery only works within first 10 seconds of app launch

If more than 10 seconds have elapsed between the app's first render and when a fatal error is thrown, expo-updates will not catch the error and error recovery code will not be triggered. Apps should check for updates very shortly after launching to ensure fixes can be pushed in case of future errors.

EAS Update deep link URL format for development builds

To load an EAS Update in a development build using a deep link, construct a URL with the format: [slug]://expo-development-client/?url=[https://u.expo.dev/project-id]/group/[group-id]. For example: my-app://expo-development-client/?url=https://u.expo.dev/675cb1f0-fa3c-11e8-ac99-6374d9643cb2/group/47839bf2-9e01-467b-9378-4a978604ab11. The [slug] is the project's slug found in the app config. The updates URL (https://u.expo.dev/[project-id]) is found in the project's app config under 'updates.url'. The [group-id] is the group ID of the update. Copy and paste the constructed URL directly into the development build's launcher screen under Enter URL Manually, or create a QR code for the URL and scan it using your device's camera.

EAS Update deep link URL components

The EAS Update deep link URL has the following components: | Part | Description | | --- | --- | | slug | The project's slug found in the app config | | ://expo-development-client/ | Necessary for the deep link to work with the expo-dev-client library | | ?url= | Defines a url query parameter | | https://u.expo.dev/[project-id] | The updates URL, found inside the project's app config under updates.url | | /group/[group-id] | The group ID of the update |

Preview EAS Updates using EAS dashboard

To preview an EAS Update using the EAS dashboard: Click the published update link in the CLI after running the command to publish an update. This will open the update's details on the Updates page in the EAS dashboard. Click Preview to open the Preview dialog. To preview the update, you can either scan the QR code with your device's camera or select a platform to launch the update under Open with Orbit.

What is the Extensions tab in a development build

When using the expo-updates library inside a development build, the Extensions tab provides the ability to load and preview a published update automatically. The Extensions tab displays one or more of the latest published updates. You can view all published updates for a specific branch by tapping the branch name in the Extensions tab.

Preview updates using development build Extensions tab

To preview a published EAS Update in a development build using the Extensions tab: First, make non-native changes locally and publish them using 'eas update'. The update will be published on a branch. After publishing, open your development build, go to Extensions, and tap Login to log in to your Expo account. This step is required for the Extensions tab to load any published updates. After logging in, an EAS Update section will appear inside the Extensions tab with one or more of the latest published updates. Tap Open next to the update you want to preview. You can view all published updates for a branch by tapping the branch name in the Extensions tab.

EAS Update service purpose

EAS Update is a service that allows you to deliver small bug fixes and updates to your users immediately as you work on your next app store release. To make updates available to builds, you create a link between a build and an update.

Give your agent this brain