Expo

Managed React Native tooling: config plugins, EAS builds and over-the-air updates.

adds it to an existing project · no account needed
Currentas published in v1.5.1

The rule

This is the whole text, exactly as your agent receives it. Nothing is held back for the paid tier.

Installing packages

  • npx expo install <package> for anything Expo-related — it resolves the version matching the installed SDK. Plain npm install produces version mismatches whose error messages point somewhere else entirely.
  • After adding a package with native code, the dev client must be rebuilt.

Native configuration

  • All native config goes in app.json — permissions, bundle identifiers, icons, plugins. Never edit ios/ or android/ directly: expo prebuild regenerates them and discards the change.
  • A library needing native setup ships a config plugin. Add it to plugins rather than patching the generated project.

Environment variables

  • Only EXPO_PUBLIC_* variables reach the app, and they are embedded in the bundle. Treat every one as public.
  • Secrets go in EAS secrets or on a server. Never in EXPO_PUBLIC_*.

Updates

  • eas update ships JavaScript only.
  • Any change touching native code — a new native dependency, a permission, an icon — requires a new build. Shipping an OTA update that expects a missing native module crashes the app on launch for everyone who receives it.
  • Update channels must match build channels.

Builds

  • Keep development, preview and production profiles separate in eas.json, each with its own environment variables and credentials.
  • Increment ios.buildNumber and android.versionCode for every store upload.

Never

  • Never commit a keystore, certificate, or .env.
  • Never point a non-production profile at production credentials.
  • Never hand-edit generated native folders.

6 formats, one per tool

Each tab is the file that tool actually reads, at the path it actually looks in. Knowing where each one looks is most of the work of supporting it.

.cursor/rules/expo.mdchand-written
---
description: Expo conventions
globs: ["**/*.tsx", "**/*.ts", "app.json", "eas.json"]
alwaysApply: false
---

# Expo

## Installing packages

- `npx expo install <package>` for anything Expo-related — it resolves the
  version matching the installed SDK. Plain `npm install` produces version
  mismatches whose error messages point somewhere else entirely.
- After adding a package with native code, the dev client must be rebuilt.

## Native configuration

- All native config goes in `app.json` — permissions, bundle identifiers, icons,
  plugins. Never edit `ios/` or `android/` directly: `expo prebuild` regenerates
  them and discards the change.
- A library needing native setup ships a config plugin. Add it to `plugins`
  rather than patching the generated project.

## Environment variables

- Only `EXPO_PUBLIC_*` variables reach the app, and they are **embedded in the
  bundle**. Treat every one as public.
- Secrets go in EAS secrets or on a server. Never in `EXPO_PUBLIC_*`.

## Updates

- `eas update` ships JavaScript only.
- Any change touching native code — a new native dependency, a permission, an
  icon — requires a new build. Shipping an OTA update that expects a missing
  native module crashes the app on launch for everyone who receives it.
- Update channels must match build channels.

## Builds

- Keep `development`, `preview` and `production` profiles separate in
  `eas.json`, each with its own environment variables and credentials.
- Increment `ios.buildNumber` and `android.versionCode` for every store upload.

## Never

- Never commit a keystore, certificate, or `.env`.
- Never point a non-production profile at production credentials.
- Never hand-edit generated native folders.

Hand-written by the module author, frontmatter and all. It is the source the four derived formats are rendered from, so a correction lands here first.

What else this module writes

The rule is one file of several. Selecting Expo contributes all of this too — merged with every other module you pick, with conflicts resolved rather than duplicated.

Environment
EXPO_PUBLIC_API_URLrequiredBase URL the app calls. One per environment.
EXPO_PUBLIC_ENVoptionalEnvironment label used for feature gating and diagnostics.
EXPO_TOKENoptionalEAS access token. CI only — never in a local `.env` that could be committed.
Dependencies
expo^57.0.0expo-dev-client^57.0.0expo-constants^57.0.0expo-updates^57.0.0eas-cli^21.5.0dev
Folders
src/config/assets/icons/assets/splash/
Checklists
checklists/expo-release.md

Advisory history

Every time this rule turned out to be wrong, and what we did about it.

No corrections yet

This rule has been accurate since it was published. That is a fact about the rule, not a promise about the future — which is the whole reason this section exists.

Pro tells you the day a correction lands that affects a repo you actually have.

See what Pro adds →

Rules people add alongside this one

Put this rule in a real project

The wizard picks the rest of the stack with you, writes all 6 formats, and leaves a manifest so check can tell you when any of it drifts.