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 insights

170 notes in this subject, read out of this brain and free to use. This is page 1 of 3.

EAS Insights navigation location

The Insights tab is accessed from the EAS dashboard navigation menu at https://expo.dev/accounts/[account]/projects/[project]/insights.

EAS Insights three main tabs

EAS Insights groups data into three tabs: App usage, Workflows, and Maestro. App usage shows usage of your app across platforms, app store versions, and time, aggregated from EAS Update requests and the expo-insights library. Workflows displays run counts, success rates, and trends for EAS Workflows. Maestro shows pass, flake, and failure trends for the Maestro end-to-end tests you run in EAS Workflows.

expo-insights installation commands

Installation commands for expo-insights library: npm: npm install --global eas-cli && eas init && npx expo install expo-insights. yarn: yarn global add eas-cli && eas init && yarn expo install expo-insights. pnpm: pnpm add --global eas-cli && eas init && pnpm expo install expo-insights. bun: bun add --global eas-cli && eas init && bun expo install expo-insights.

Maestro insights availability

Maestro insights is available on the Production and Enterprise plans.

Maestro insights filter options

You can narrow the Maestro insights data down by workflow, status (passed, flaky, failed), tag, or branch.

Maestro tab in EAS Insights location

To view Maestro insights, open your project in the EAS dashboard, select Insights from the navigation menu, and then select the Maestro tab.

EAS Insights Workflows tab filters

The Workflows tab provides filters to narrow data by workflow, run status (success, failure, canceled), trigger type (manual, schedule, or GitHub event), or git ref. You can also search by workflow name.

EAS Insights Workflows availability

Workflows insights is available on the Production and Enterprise plans. Access the Workflows tab by opening your project in the EAS dashboard, selecting Insights from the navigation menu, then selecting the Workflows tab.

Monitor update adoption in EAS Update

You can monitor the adoption of updates from the EAS website. You can also roll out and roll back updates from the website UI.

EAS Update includes deployments dashboard and insights

EAS Update provides a deployments dashboard that helps visualize which updates are being sent to builds. Updates work in concert with insights to provide data on the adoption rates of updates with users.

EAS requests page metadata and scope

The EAS Hosting requests page displays a list of all requests against the service with metadata including status, browser, region, and duration per request. Requests can be viewed at the project level or the deployment level. The list includes all requests to the service, including requests to API routes.

EAS API routes and server functions logging

All logs from API routes and server functions, including console.log, console.info, console.error, and similar logging calls, are automatically recorded on the deployment level logs page in EAS Hosting.

EAS Hosting dashboard inspection pages

The EAS Hosting dashboard allows inspection of crashes, logs, and requests that occur in API routes. Crashes are viewed on the Hosting crashes page at expo.dev/accounts/[accountName]/projects/[projectName]/hosting/crashes. Logs are viewed on the deployment level logs page by navigating to Hosting deployments, selecting a deployment, and clicking Logs. Requests are viewed at the project level at expo.dev/accounts/[accountName]/projects/[projectName]/hosting/requests or at the deployment level by navigating to Hosting Deployments, selecting a deployment, and clicking Requests.

EAS crash grouping and details

Crashes are any uncaught errors thrown while a request was handled, which prevent a response from being returned. Crashes are grouped on the dashboard, so if similar crashes are detected, only one line item will be shown. The crash details display the stack trace and metadata for both the first and last known occurrence of the crash.

Custom endpoint with standard OTLP paths

The endpoint URL path includes the project ID before the standard /v1/metrics and /v1/logs OTLP paths. If the backend expects the standard OTLP path without the project ID prefix, send the data to an OpenTelemetry Collector that receives it and re-exports it to the backend.

Observe.configure() example with sampleRate

Example of using sampleRate to sample metrics from 25% of installations: import { Observe } from 'expo-observe'; Observe.configure({ sampleRate: 0.25, });

Observe.configure() example with dispatchInDebug

Example of enabling metrics dispatch in debug builds: import { Observe } from 'expo-observe'; Observe.configure({ dispatchInDebug: true, });

Custom endpoint requires app rebuild

The endpoint URL is baked into the native layer of the app at build time, so changing it requires regenerating native code. After updating the app config with a new endpointUrl, run npx expo prebuild and create a new build to apply the change.

dispatchInDebug option in Observe.configure()

The dispatchInDebug option is a boolean that defaults to false. It controls whether metrics collected in debug builds are dispatched. A build is treated as a debug build if either the native app is a debug build or the JS bundle is a development bundle (when __DEV__ is true). This option has no effect on release builds.

integrations option in Observe.configure()

The integrations option is an object that defaults to undefined. It provides opt-in settings for EAS Observe integrations, such as Expo Router and React Navigation, or custom third-party integrations.

dispatchingEnabled option in Observe.configure()

The dispatchingEnabled option is a boolean that defaults to true. It controls whether collected events are sent to the server. When set to false, nothing is dispatched regardless of sampleRate or dispatchInDebug.

Development metrics collection warning

dispatchInDebug should only be enabled when testing EAS Observe integration. Development and debug performance differs significantly from production, so collecting development/debug metrics may distort the results shown in the dashboard.

Custom endpoint setup in app.json

To configure a custom endpoint for EAS Observe, add the endpointUrl to app.json like this: { "expo": { "extra": { "eas": { "observe": { "endpointUrl": "https://your-custom-endpoint.com" } } } } }

sampleRate option in Observe.configure()

The sampleRate option is a number that defaults to undefined. It represents a fraction of installations that dispatch metrics, with values in the range [0, 1]. The sampling decision is deterministic per installation, meaning each installation is permanently in-sample or out-of-sample for a given rate, providing a consistent slice of installations rather than random sessions. Values outside [0, 1] are clamped to the nearest edge (0 always drops, 1 always dispatches).

Sampling determinism and out-of-sample behavior

Sampling in EAS Observe is deterministic per installation. Each installation is permanently either in-sample or out-of-sample for a given sampleRate, providing stable behavior across app launches. Out-of-sample devices drop pending metrics rather than accumulating them. Lowering the sampleRate later does not retroactively send earlier sessions from previously out-of-sample installations.

Observe.configure() example with environment and dispatchingEnabled

Example of using Observe.configure(): import { Observe } from 'expo-observe'; Observe.configure({ environment: 'production', dispatchingEnabled: true, });

environment option in Observe.configure()

The environment option is a string that defaults to process.env.NODE_ENV. It provides a metadata label for observability events and can be overridden when calling configure().

Observe.dispatchEvents() example

Example of manually dispatching events: import { Observe } from 'expo-observe'; await Observe.dispatchEvents();

Latest and previous release comparison

Without a release filter, App startup cards show the metric for the latest and previous releases at the top of the card. This makes regressions easier to spot at a glance.

Dashboard summary section

The top of the dashboard shows a summary of the data in view including active users, releases, builds, and updates counts. These counts update as you change filters. Click Show all to clear release filtering and see aggregate counts across every release.

Dashboard filter options

Filters control which events are included in the metrics. Platform filter: Android or iOS. Environment filter: filter to a specific environment such as production or preview, defaults to All environments. Time range filter: 1 hour, 12 hours, 1 day, 3 days, 7 days, 14 days, 21 days, 30 days, or 60 days, defaults to Last 14 Days. Release filter: filter to a specific app version, a specific native build, or a specific OTA update.

Recent updates table columns and sorting

The per-update table lists every update fetched in the time range with the following columns: Update (the update ID and message), Downloads (number of unique devices that downloaded the update), Median download (median download time for that update, visualized as a bar relative to the slowest update in the table), P90 (90th percentile download time for that update), and First downloaded (when the first device fetched the update). You can sort by Downloads, Median download, P90, or First downloaded in ascending or descending order. Click a row to drill into the individual download events for that update.

Update download time chart metrics and statistical breakdowns

The update download time chart shows aggregate download time across all updates fetched in the selected time range. Statistical breakdowns include Median, Avg, Min, Max, P90, and P99. Update markers on the chart indicate when each update first downloaded. Click a marker to see the update ID, version, and metrics at that point.

CLI commands for querying events

Use eas observe:events to list event names with counts. Use eas observe:events <event-name> to show individual events for a specific event name. Use eas observe:events --all-events --json to show all events across all names in JSON output. Run eas observe:events --help for the full list of flags including time range, platform, and session ID.

Observe.logEvent API basic usage

Call Observe.logEvent from anywhere in your app to record named events. The first argument is the event name, which should be a stable, dot-separated identifier. The dashboard groups events by exact name. Example: Observe.logEvent('onboarding.completed');

View events in EAS Observe dashboard

Navigate to Observe > Events in your project dashboard. The default view lists distinct event names with their counts in the selected time range. Click an event name to see individual events with their timestamps, attributes, and the session they belong to.

Event persistence and dispatch

Events are persisted on-device, batched, and dispatched on the next flush as OpenTelemetry log records. They appear in the Events tab of the EAS Observe dashboard and are queryable from the EAS CLI.

Event body parameter

Use the body parameter in Observe.logEvent to provide a free-form message that complements the structured attributes.

Event naming conventions

Use lowercase, dot-separated names for events such as task.completed, onboarding.skipped, report.exported. Pick a vocabulary and stick to it, because the dashboard groups by exact event name, so report_exported and report.exported appear as separate rows. Avoid Personally Identifiable Information (PII) in event names, attribute keys, and attribute values.

Event displayName parameter

Use displayName to provide a human-friendly label for the event in the dashboard. The display name will only be used in the session timeline view.

Event attributes parameter

Pass an attributes map as the second parameter to Observe.logEvent to record context with the event. Supported attribute value types are: string, number, boolean, arrays, and nested objects. Other JS values like Date, undefined, and functions are dropped.

Event severity levels

Events default to 'info' severity. Override with the severity option to use: 'trace', 'debug', 'info', 'warn', 'error', or 'fatal', ordered from lowest to highest.

Observe.logEvent with all parameters example

Example showing all parameter types: Observe.logEvent('sync.failed', { severity: 'error', body: 'Cache evicted because disk pressure exceeded the configured threshold.', attributes: { reason: 'network_timeout', evictedItemCount: 42, freedBytes: 1048576 }, displayName: 'Sync failed' });

EAS project link requirement

Your app must be linked to an EAS project for EAS Observe to work. Ensure `extra.eas.projectId` in your app config includes the project ID, or create one by running `eas init`.

Install expo-observe library

Install `expo-observe` after ensuring you have the latest version of `expo`. The installation command is `npx expo install expo-observe` (npm), `yarn expo install expo-observe` (yarn), `pnpm expo install expo-observe` (pnpm), or `bun expo install expo-observe` (bun).

Create new build after installing expo-observe

After installing `expo-observe` and adding the instrumentation, create a new build of your app with `eas build`.

EAS Observe requires Expo SDK 55 or later

EAS Observe requires SDK 55 or later. You can check your SDK version with `npx expo-doctor` and update dependencies with `npx expo install --fix`.

EAS CLI commands for querying metrics

The EAS CLI provides four commands for querying metrics from the terminal: `eas observe:versions` (lists app versions with build IDs, update group IDs, and release dates), `eas observe:metrics-summary` (shows aggregated performance metrics grouped by app version), `eas observe:metrics` (shows individual performance metric events ordered by value with session and device metadata), and `eas observe:events` (shows individual events emitted by the app via Observe.logEvent). Run any command with `--help` to see available flags and arguments.

Expo Router integration prerequisites

The Expo Router integration for EAS Observe requires Expo SDK 56 or later. On earlier SDKs, expo-observe still tracks app-wide metrics, but per-route navigation events are not emitted. An app must already be using EAS Observe with expo-observe installed. Expo Router must be installed in the app; if the package is not installed, the integration becomes a silent no-op.

Enable Expo Router integration code example

This example shows enabling the Expo Router integration for EAS Observe at module scope before any screen mounts: ```tsx src/app/_layout.tsx import { Observe } from 'expo-observe'; Observe.configure({ integrations: { 'expo-router': true }, }); ```

Per-route warm render (warm_ttr) metric

The warm_ttr metric measures time from when a navigation action is dispatched to when the destination screen first becomes focused, but for screens that were already rendered before focus, typically because they were preloaded via Link prefetch or the user navigated back to them. Event parameters are: routeName (string, route pattern), url (string, resolved pathname), urlHidden (boolean, present as true when url is omitted due to filtering), and routeParams (object, resolved route params).

useObserve hook code example

This example shows using the useObserve() hook to mark when a screen becomes interactive: ```tsx src/app/(tabs)/index.tsx import { useObserve } from 'expo-observe'; import { useEffect } from 'react'; export default function Home() { const { markInteractive } = useObserve(); useEffect(() => { markInteractive(); }, [markInteractive]); return (/* your screen content */); } ```

Filter sensitive URL parameters (SDK 57+)

Available in SDK 57 and later. By default, the Expo Router integration includes the resolved url and all serializable route and query parameters in routeParams. Pass sensitive parameter keys to filteredParams to remove them from events. The integration removes filtered keys from routeParams, and the event omits url and includes urlHidden: true instead. routeName is not affected because it is a pattern and never contains parameter values.

Filter sensitive URL parameters code example

This example shows filtering sensitive URL parameters like userId and token from EAS Observe events: ```tsx src/app/_layout.tsx import { Observe } from 'expo-observe'; Observe.configure({ integrations: { 'expo-router': { filteredParams: ['userId', 'token'], }, }, }); ```

React Navigation static configuration integration setup

With static configuration, create the navigation ref yourself using `useNavigationContainerRef()`, pass it to the `<Navigation>` element returned by `createStaticNavigation()`, and wrap the element in `<ObserveNavigationProvider>` with the same ref. The provider listens to navigation events through the ref and records per-screen render timings.

ObserveNavigationProvider must be app ancestor for useObserve()

With static configuration, `ObserveNavigationProvider` does not render a container of its own. It listens to the `navigationRef` you pass. It must be an ancestor of every screen so that `useObserve()` works inside them.

Third-party packages can integrate with EAS Observe

Third-party packages can integrate with EAS Observe to send events that help developers identify performance and usage issues. Events should describe actionable issues that developers can fix, such as an image much larger than the device's screen, a background task taking too long, or a native resource loading slowly.

SDK requirement for third-party EAS Observe integrations

Third-party integrations require SDK 57 and later to access Observe.registerIntegration().

Example package.json for third-party EAS Observe integration

Example of adding expo-observe as an optional dependency: ```json { "peerDependencies": { "expo-observe": ">={{expoSdkVersion}}" }, "peerDependenciesMeta": { "expo-observe": { "optional": true } }, "devDependencies": { "expo-observe": "^{{expoSdkVersion}}" } } ```

Example integration type declaration for third-party package

Example of declaring integration configuration types: ```ts export type YourPackageIntegrationConfig = { thresholdMs?: number; }; declare module 'expo-observe' { interface ObserveIntegrationsConfig { 'your-package'?: boolean | YourPackageIntegrationConfig; } } ```

Give your agent this brain