expo trained
Read this before expo-overview; use the root routing table to select one guide. The guides carry API detail; this page carries tested routing and judgment.
mental model
An Expo app is a React Native app with the expo package; the installed SDK sets the compatible package and API surface. Expo Go is a limited learning environment, while a development build contains the app's own native code. EAS is an optional family of build, update, hosting, and release services. An EAS Update reaches a build through its channel's branch only when platform and runtime version match. Sources: Expo SDK, development environment, EAS Update matching.
examples
Run these from an existing Expo project. CI=1 makes the compatibility check noninteractive and exits nonzero on drift:
node -p "require('./package.json').dependencies?.expo ?? 'Expo absent'"CI=1 ./node_modules/.bin/expo install --check
A workspace root can keep Expo in devDependencies rather than as an app dependency; there the first command reports Expo absent and the check reports a version mismatch. That root result says nothing about a live app: run both commands in the owning app. Expo documents expo install --check as the compatibility check. For a new app, use the documented npx create-expo-app@latest path.
best practices
- Read the app package, not only the workspace root, for its installed
expoversion and versioned API docs before choosing packages. Usenpx expo installto select SDK-compatible versions and--checkto detect drift. - Choose a development build when the task uses custom native code; verify native changes in a newly built app. Expo's development build guide explains the native boundary.
- Treat a successful export or build as one gate. Observe the user action on the target runtime before claiming the feature works.
strengths
Expo supplies a coherent SDK, Router, native modules, and development builds for React Native apps; EAS can supply hosted build and update workflows when the project uses them. Expo project setup and EAS services describe these surfaces.
weaknesses / pain points
Expo Go cannot represent an app's custom native modules, so production app behavior needs a development or release build. EAS services have plan limits; check the account's current plan before relying on a cloud path. Sources: development environment, EAS plans.
gotchas
- An
ios/orandroid/folder existing does not establish that Expo is the current frontend. Confirm theexpodependency and live project owner first. - An OTA update cannot deliver a native API change to an incompatible build; compare runtime version, platform, and channel before debugging the UI. EAS Update matching.
- The EAS guide descriptions call several services "paid". That is overbroad: Expo documents free quotas for Build and Update. Check the current plan for each service.
known bugs
No app-level Expo bug is recorded here. Archived known-issue lists are diagnostic leads only; they never prove that a current project carries those defects.
practiced cases
- Route by the live project contract. A workspace's root AGENTS.md and its app-level contracts can declare Capacitor the active mobile shell and retire the Expo clients. In that case no Expo route applies to those projects; Capacitor work goes to capacitor.
- SDK compatibility diagnostic. In a workspace whose root has
expo@57.0.17indevDependencies,CI=1 ./node_modules/.bin/expo install --checkexits 1 expecting~57.0.25. That is a valid diagnostic for the root, not proof about an app. Before reaching for the documentedexpo install --fixpath, run the check in the app that owns the dependency. - CommonJS helper under ESM. Node in ES module scope rejects a CommonJS helper saved as
.jswithrequire is not defined in ES module scope. Saving it as.cjslets the invocation reach the@expo/uipresence check in a project without that package. Component extraction with an installed@expo/uiremains unverified.