Labsco
expo logo

eas-update-insights

✓ Official2,200

by expo · part of expo/skills

Check the health of published EAS Updates: crash rates, install/launch counts, unique users, payload size, and the split between embedded and OTA users per…

🔥🔥🔥✓ VerifiedFreeQuick setup
🧩 One of 7 skills in the expo/skills package — works on its own, and pairs well with its siblings.

This is the playbook your agent receives when the skill activates — you don't need to read it to use the skill, but it's here to audit before installing.

by expo

Check the health of published EAS Updates: crash rates, install/launch counts, unique users, payload size, and the split between embedded and OTA users per… npx skills add https://github.com/expo/skills --skill eas-update-insights Download ZIPGitHub2.2k

EAS Update Insights

Query the health of published EAS Updates directly from the CLI: launches, failed launches, crash rates, unique users, payload size, the embedded-vs-OTA user split per channel, and the most popular updates per runtime version. The data is the same data that powers the update and channel detail pages on expo.dev; these commands expose it in the terminal in human and JSON form.

When to use this skill

Use this when the user wants to assess the health or adoption of a published EAS Update: crash rates, install counts, unique users, bundle size, or the split between embedded and OTA users on a channel.

Example prompts:

  • "How is the latest update doing?"

  • "Is the latest update healthy?"

  • "Is the new release crashing more than the last one?"

  • "How many users are on the latest update vs the embedded build?"

  • "Which update is most popular on production right now?"

  • "How big is our update bundle?"

Also fits: post-publish rollout monitoring and regression detection.

Don't use when the user needs per-user crash detail or device-level reporting; this skill only exposes aggregate EAS metrics.

Commands at a glance

Command Purpose eas update:list Discover recent update groups, their group IDs, and branch names eas update:insights <groupId> Per-platform launches, failed launches, crash rate, unique users, payload size, daily breakdown eas update:view <groupId> --insights Update group details + the same metrics appended eas channel:insights --channel <name> --runtime-version <version> Embedded/OTA user counts, most popular updates, cumulative metrics for a channel + runtime

All of these support --json --non-interactive for programmatic parsing.

Discovering IDs

Before querying insights for an update group, you need its group ID. Use eas update:list with either --branch <name> (updates on that branch) or --all (updates across all branches). Always pass --json --non-interactive when running non-interactively; without a branch/--all flag the command will otherwise prompt for a branch selection:

# Latest group id across all branches
eas update:list --all --json --non-interactive | jq -r '.currentPage[0].group'

# Latest group id on a specific branch
eas update:list --branch production --json --non-interactive | jq -r '.currentPage[0].group'

The JSON response has a currentPage array with one entry per update group (both platforms of the same publish are collapsed into one entry):

{
 "currentPage": [
 {
 "branch": "production",
 "message": "\"Fix checkout crash\" (1 week ago by someone)",
 "runtimeVersion": "1.0.6",
 "group": "03d5dfcf-736c-475a-8730-af039c3f4d06",
 "platforms": "android, ios",
 "isRollBackToEmbedded": false
 }
 ]
}

Entries also carry codeSigningKey and rolloutPercentage, but only when those features are in use for the group (undefined values are omitted from the JSON output).

When called with --branch <name>, the response also includes name (the branch name) and id (the branch ID) at the top level.

eas update:insights <groupId>

Shows launches, failed launches, crash rate, unique users, launch asset count, and average payload size for a single update group, broken down per platform (iOS, Android), plus a daily breakdown of launches and failures.

Basic use

eas update:insights 03d5dfcf-736c-475a-8730-af039c3f4d06

Flags

Flag Description --days <N> Look back N days. Default: 7. Mutually exclusive with --start/--end. --start <iso-date> / --end <iso-date> Explicit time range, e.g. --start 2026-04-01 --end 2026-04-15. --platform <ios|android> Filter to a single platform. Omit to see all platforms in the group. --json Machine-readable output. Implies --non-interactive. --non-interactive Required when scripting.

JSON output shape

Top level: groupId, timespan (start, end, daysBack), and platforms[] with one entry per platform the group was published to. Each platform entry has updateId, totals (uniqueUsers, installs, failedInstalls, crashRatePercent), payload (launchAssetCount, averageUpdatePayloadBytes), and a daily[] time series of { date, installs, failedInstalls }.

For the complete schema and field reference, see references/update-insights-schema.md.

Fields that matter for health assessment:

  • platforms[].totals.crashRatePercent, computed as failedInstalls / (installs + failedInstalls) * 100. Zero when there are no installs.

  • platforms[].totals.installs and uniqueUsers give the adoption signal.

  • platforms[].daily is a time series, useful for spotting a sudden spike in failures.

Errors

  • Could not find any updates with group ID: "<id>" — group doesn't exist or you lack access.

  • Update group "<id>" has no ios update (available platforms: android)--platform ios was used but the group wasn't published for iOS.

  • EAS Update insights is not supported by this version of eas-cli. Please upgrade ... — the server deprecated a field the CLI relies on. Run npm install -g eas-cli@latest.

eas update:view <groupId> --insights

Extends the standard update:view output with the same per-platform insights, inline.

# Human-readable
eas update:view 03d5dfcf-... --insights
eas update:view 03d5dfcf-... --insights --days 30

# JSON: wrapped as { updates: [...], insights: {...} }
eas update:view 03d5dfcf-... --json --insights

Without --insights, update:view behaves exactly as before — no JSON shape change for existing consumers. The --days / --start / --end flags only apply when --insights is set; passing them alone errors.

eas channel:insights --channel <name> --runtime-version <version>

Shows, per channel, how many users are on the embedded build vs over-the-air updates and which updates are pulling the most traffic. Must be run from an Expo project directory.

Basic use

eas channel:insights --channel production --runtime-version 1.0.6

Flags

Flag Description --channel <name> Required. The channel name (e.g. production, staging). --runtime-version <version> Required. Match exactly what was published. Check runtimeVersion values in update:list. --days <N> Look back N days. Default: 7. --start / --end Explicit time range, like update:insights. --json / --non-interactive Machine-readable output.

JSON output shape

Top level: channel, runtimeVersion, timespan, embeddedUpdateTotalUniqueUsers, otaTotalUniqueUsers, mostPopularUpdates[] (each with rank, groupId, message, platform, totalUniqueUsers), cumulativeMetricsAtLastTimestamp[], plus chart-shaped uniqueUsersOverTime and cumulativeMetricsOverTime objects with labels and datasets.

For the complete schema and field reference, see references/channel-insights-schema.md.

Fields that matter:

  • embeddedUpdateTotalUniqueUsers is the count of users running the embedded (binary-bundled) build.

  • mostPopularUpdates[] is updates ranked by totalUniqueUsers. Caveat: this is the top-N the server returns; otaTotalUniqueUsers is a sum of that list and may undercount total OTA reach if more than top-N updates are active.

  • uniqueUsersOverTime and cumulativeMetricsOverTime are daily data series for charting.

Errors

  • Could not find channel with the name <name> — typo or wrong account.

  • "No update launches recorded" in the table / empty mostPopularUpdates in JSON — no OTA update has been launched for that channel + runtime yet. Usually means the channel is still serving the embedded build only.

Common workflows

Verify the update I just published is healthy

# 1. Grab the latest publish on production
GROUP_ID=$(eas update:list --branch production --json --non-interactive \
 | jq -r '.currentPage[0].group')

# 2. Give it some adoption time (minutes to hours), then check crash rate
eas update:insights "$GROUP_ID" --json --non-interactive \
 | jq '.platforms[] | {platform, installs: .totals.installs, crashRate: .totals.crashRatePercent}'

Compare the crashRate across platforms and against previous releases; sudden spikes or asymmetric behaviour (iOS spiking while Android is flat, or vice versa) is the signal to investigate.

Compare adoption between two channels

for channel in production staging; do
 echo "--- $channel ---"
 eas channel:insights --channel "$channel" --runtime-version 1.0.6 --json --non-interactive \
 | jq '{
 channel,
 embedded: .embeddedUpdateTotalUniqueUsers,
 ota: .otaTotalUniqueUsers,
 topUpdate: .mostPopularUpdates[0]
 }'
done

Detect a rollout regression in the last 24 hours

eas update:insights "$GROUP_ID" --days 1 --json --non-interactive \
 | jq '.platforms[] | select(.totals.crashRatePercent > 1)'

Summarize group metrics for release notes

eas update:view "$GROUP_ID" --insights --days 30

Human-readable group details plus 30 days of launches/failures per platform — suitable for pasting into a changelog or incident review.

Output tips

  • Pipe JSON through jq; payloads are structured for easy filtering.

  • --json implies --non-interactive, but passing both is explicit and scripting-friendly.

  • Dates in daily[].date are UTC ISO timestamps; the human-readable table renders them as YYYY-MM-DD (UTC).

  • The CLI table labels say "Launches" / "Crashes" while JSON uses installs / failedInstalls. Same field, different display name.