Adapters
Expo Updates adapter
The expo-updates (EAS Update) adapter: reports the active update id and edge-triggered download events so the engine can put fresh OTA updates on probation. Recommendation-only.
@release-health/adapter-expo-updates connects
expo-updates (EAS Update) to the health
engine. It reports the active update id and edge-triggered download and error events so fresh OTA
updates go on probation and crash loops are detected.
Install
npm install @release-health/adapter-expo-updates react-native-release-health expo-updatesexpo-updates is a peer dependency; the host app owns its version (SDK 55 or newer).
Usage
import { ReleaseHealth } from 'react-native-release-health';
import { expoUpdatesAdapter } from '@release-health/adapter-expo-updates';
ReleaseHealth.init({
adapter: expoUpdatesAdapter(),
sinks: [
/* httpSink(...), ... */
],
});Optionally pass the module explicitly. This is equivalent at runtime, and it gives you a compile-time check that your installed expo-updates version still matches the shape the adapter expects:
import * as Updates from 'expo-updates';
expoUpdatesAdapter({ updatesModule: Updates });When applying a downloaded update in the same session, tell the engine first so a reload during probation restarts the probation timer instead of counting against the update:
ReleaseHealth.notifyReload();
await Updates.reloadAsync();Behavior
- Recommendation-only. expo-updates has no client-side rollback API (rollbacks are server
directives, for example
eas update:roll-back-to-embedded), so the adapter does not implementrollback(). The engine detects this and stays in recommendation-only mode;autoRollback: truelogs a warning instead of failing. Subscribe withReleaseHealth.onRollbackRecommended()and trigger the server-side rollback from your own tooling. downloadedfires once per new update id. The adapter watches expo-updates state-change events and emits on edges, not on every snapshot. A download that already happened before the adapter subscribed (a pending update from a previous session) is treated as baseline and not re-announced, so the crash-loop counter is not reset.appliedis never emitted. expo-updates applies updates on the next launch (or an explicitreloadAsync()); the engine detects the apply by comparing the active update id against its pending marker at launch.- Degrades gracefully. In development builds, Expo Go, or when expo-updates is missing or misconfigured, the adapter reports the embedded bundle, emits no events, and logs a single warning. It never throws into the host app.
Known limitation: server rollback-to-embedded
A server rollback-to-embedded (eas update:roll-back-to-embedded) is delivered by staging the
embedded bundle as the newest update, so expo-updates reports the embedded manifest in the
downloaded slot. The adapter therefore emits one update_downloaded carrying the embedded
bundle's update id. This is harmless: on the next launch the embedded bundle runs, the active
update id is null, so nothing is put on probation, and the marker is superseded by the next real
update. It does mean a rollback-to-embedded shows up in your event stream as an
update_downloaded for the embedded id rather than as a distinct rollback event. More caveats
like this are collected in Limitations.
Options
| Option | Default | Description |
|---|---|---|
updatesModule | require('expo-updates') | Alternative module implementation (tests, custom wrappers) |
warn | console.warn | Warning channel |