Agent skill

Expo

by ericrisco in ericrisco/rsc-harness

A skill your agent uses when shipping a React Native app with Expo — EAS Build/Submit/Update, eas.json profiles and channels, config plugins, prebuild/CNG, runtime-version policy, OTA updates that…

MITAuto-check: notesMobile

Install Expo

skills CLI
$ npx skills add ericrisco/rsc-harness --skill expo -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ericrisco/rsc-harness expo --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/expo .claude/skills/expo && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
expo
GitHub stars
167
Token cost
~2.9k tokens
SKILL.md length
1,222 words
Files
6 (incl. scripts, references)
Skills in repo
227
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when shipping a React Native app with Expo — EAS Build/Submit/Update, eas.json profiles and channels, config plugins, prebuild/CNG, runtime-version policy, OTA updates that…

  • Works in 4 steps: npx expo install expo@latest --fix —… → npx expo-doctor@latest — catch deps that… → npx expo prebuild --clean — regenerate… → …
  • Shipping a React Native app with Expo — EAS Build/Submit/Update
  • SKILL.md covers What this skill owns, Decision rules, The shipping pipeline (core) and EAS Update mental model, plus 7 more sections
  • Runs Shell scripts from its folder; calls eas and npx

What it does

Expo is an agent skill from ericrisco/rsc-harness. Use when shipping a React Native app with Expo — EAS Build/Submit/Update, eas.json profiles and channels, config plugins, prebuild/CNG, runtime-version policy, OTA updates that never land, SDK upgrades, the New Architecture. NOT RN UI, navigation or native-module authoring (that is react-native), NOT a Dart app (that is flutter).

Its SKILL.md is about 2.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/config-plugins.md`).

It sits in Mobile, covering Cross-platform mobile apps. It works with Expo, React Native, Flutter and Dart. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.

When your agent uses it

  • Shipping a React Native app with Expo — EAS Build/Submit/Update
  • Eas.json profiles and channels
  • Runtime-version policy
  • OTA updates that never land

Example prompts

  • “/expo”

Requirements

  • Node.js
  • A Bash shell

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. npx expo install expo@latest --fix — bump SDK and align every dependency.
  2. npx expo-doctor@latest — catch deps that never made the New-Arch jump before you build.
  3. npx expo prebuild --clean — regenerate native dirs (managed/CNG apps).
  4. Build a development/preview binary on a device before promoting to production.

What it can do on your machine

Read from SKILL.md and the folder at commit e3d5b33. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/ (Shell), which the agent can run.

    Shell commands in SKILL.md call:

    • eas
    • npx

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npx, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Expo loads about 2.9k tokens when it runs, and up to ~5.4k if it reads all its reference files. Until then it costs about 85 tokens; SKILL.md has 1,222 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~85
When it runs · the whole SKILL.md, loaded when a task matches
~2.9k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~5.4k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NoteMentions a .env fileSKILL.md:180
    through **EAS environment variables** / `.env` files

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from ericrisco/rsc-harness at commit e3d5b33, republished under its MIT licence (© ericrisco). 1,222 words, ~2,859 tokens.

Download SKILL.mdSave it as .claude/skills/expo/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.
name
expo
description
Use when shipping a React Native app with Expo — EAS Build/Submit/Update, eas.json profiles and channels, config plugins, prebuild/CNG, runtime-version policy, OTA updates that never land, SDK upgrades, the New Architecture. NOT RN UI, navigation or native-module authoring (that is `react-native`), NOT a Dart app (that is `flutter`).
tags
expo, eas, react-native, mobile, ota-updates, app-store
recommends
react-native, github-actions, ship, deployment, secure-coding
origin
risco

Expo & EAS: shipping React Native

Hand-off — the app vs its motion. This skill owns the Expo platform: router, config plugins, EAS, native modules, store builds. Animation and gestures — Reanimated worklets, the UI runtime, sheets, screen transitions, press feedback, haptics, motion that stutters on a real device — are ../motion-craft/SKILL.md's.

What this skill owns

Expo is the toolchain and EAS cloud platform layered on React Native: cloud builds, store submission, over-the-air JS updates, and native configuration declared in JavaScript instead of hand-edited Xcode/Gradle projects. This skill owns the shipping pipeline and native-config-via-JS.

The verb rule of thumb: if the verb is build / submit / update / prebuild / plugin / EAS / channel / runtime-version, you are in expo. If it is render / navigate / animate / bridge / write a native module, route to react-native. Other exits: web React/hooks/state → react, a Dart app → flutter, native-only Swift/Kotlin → swift-ios/kotlin-android, a desktop wrapper → tauri/electron, CI unrelated to EAS → github-actions.

Current stable as of 2026-06-02: Expo SDK 55 — React Native 0.83.1, React 19.2.0, shipped 2026-02-25. SDK 56 is in beta (beta opened 2026-05-06, ~2-week window; RN 0.85.2, React 19.2.3) — upcoming, not yet shipped stable. Both run exclusively on the New Architecture; the Legacy Architecture was removed in SDK 55.

Decision rules

SituationDo thisWhy / not that
New app, want config-as-JSmanaged + prebuild (CNG) — no committed ios//android/native dirs are regenerable artifacts; hand-edits get blown away
You truly need to hand-edit native code long-termbare (commit ios//android/)last resort; you lose prebuild --clean upgrades
Quick demo, only Expo-SDK modulesExpo Gozero build, but custom native deps will crash
Any custom native dependency or plugindev build (developmentClient: true)Expo Go cannot load arbitrary native code
Runtime version, picking a policyfingerprint (auto-bumps on native change)safest default; prevents serving JS to an incompatible binary
Runtime tied to your release versionappVersionsimpler, but you must remember to bump it on native changes

The shipping pipeline (core)

Four EAS verbs, in this order: prebuild → build → submit → update.

bash
npx expo prebuild --clean      # regenerate native dirs from app config + plugins (CNG)
eas build -p ios --profile production       # cloud-build the binary (.ipa/.aab)
eas submit -p ios --profile production      # upload to App Store / Play Store
eas update --branch production --message "fix typo"   # ship JS-only over the air

prebuild is only needed for managed/CNG apps and runs automatically inside eas build; run it locally to inspect or to verify a plugin. Build/submit ship a new binary; update ships JS only — anything touching native code needs a new build.

Minimal eas.json with the three default profiles plus channels. Each build is stamped with a channel; a channel maps to a same-named EAS Update branch by default (SDK 55 stable builders: RN 0.83.1, Xcode 26 on iOS, Android 16 target):

jsonc
{
  "cli": { "version": ">= 16.0.0" },
  "build": {
    "development": {
      "developmentClient": true,
      "distribution": "internal",
      "channel": "development"
    },
    "preview": {
      "distribution": "internal",
      "channel": "preview"
    },
    "production": {
      "channel": "production",
      "autoIncrement": true
    }
  },
  "submit": {
    "production": {}
  }
}

Run scripts/verify.sh inside an Expo project to gate eas.json, the runtime policy, committed secrets, and New-Arch readiness.

EAS Update mental model

Runtime version is the compatibility gate. An update applies to a build only when BOTH the platform AND the runtimeVersion match exactly — there is no "close enough". The chain is: build stamped with a channel → channel points at a branch → you publish updates to a branch. Updates flow only down a matching runtime within the linked branch.

The #1 footgun: a hardcoded runtimeVersion that drifts from the binary, so the update silently never installs and you stare at unchanged devices.

jsonc
// BAD — hardcoded string in app.json; bump a native dep and every old build
// silently stops matching, so your "shipped" OTA never reaches users.
{ "expo": { "runtimeVersion": "1.0.0" } }
jsonc
// GOOD — fingerprint policy: EAS hashes the native runtime and auto-bumps the
// runtime version whenever native code/config changes, so updates only ever
// reach binaries that can actually run them.
{ "expo": { "runtimeVersion": { "policy": "fingerprint" } } }

Inspect, branch ops, rollouts/rollbacks, republish, and the full "update not applying" decision flow → references/eas-update.md.

Config plugins / CNG

Never hand-edit ios/ or android/ — they are ephemeral, regenerated by npx expo prebuild --clean from app.config + plugins + autolinking. To change native config, write a config plugin (a function in the plugins array) or use a mod like withInfoPlist / withAndroidManifest.

ts
// app.plugin.ts — add an iOS Info.plist key during prebuild, the CNG way.
import { ConfigPlugin, withInfoPlist } from "expo/config-plugins";

const withCameraUsage: ConfigPlugin<{ reason: string }> = (config, { reason }) =>
  withInfoPlist(config, (cfg) => {
    cfg.modResults.NSCameraUsageDescription = reason;
    return cfg;
  });

export default withCameraUsage;
ts
// app.config.ts — dynamic config; reference the plugin with its options.
export default {
  expo: {
    name: "MyApp",
    runtimeVersion: { policy: "fingerprint" },
    plugins: [["./app.plugin.ts", { reason: "Scan receipts" }]],
  },
};

Plugin anatomy, dangerous mods, mod ordering, and prebuild troubleshooting → references/config-plugins.md.

New Architecture & SDK upgrade

The Legacy Architecture is gone. SDK 54 was the last release to ship it; SDK 55 (2026-02-25, current stable) removed it entirely, and the SDK 56 beta builds on that. On any supported SDK you are already on the New Architecture — it is always enabled and cannot be turned off. The newArchEnabled flag was deleted from app.json in SDK 55; if you still carry one, it is dead config — remove it. There is no legacy fallback to lean on, so a dependency that only works on the old architecture is now a hard blocker, not a "flip the flag back" escape hatch.

Upgrade checklist:

  1. npx expo install expo@latest --fix — bump SDK and align every dependency.
  2. npx expo-doctor@latest — catch deps that never made the New-Arch jump before you build.
  3. npx expo prebuild --clean — regenerate native dirs (managed/CNG apps).
  4. Build a development/preview binary on a device before promoting to production.

Two upgrade tripwires: every Android app is edge-to-edge (on since SDK 54, non-negotiable) — audit manual inset/status-bar code. And SDK 55+ ships Hermes bytecode diffing for EAS Update (~75% smaller OTA downloads) automatically; you get it for free once both the build and the update are on SDK 55+.

Show full SKILL.md (448 more words)Show less

Credentials & secrets

  • Let EAS manage credentials (signing keys, provisioning profiles) by default — it stores and rotates them server-side so they never touch the repo.
  • Supply per-profile config through EAS environment variables / .env files scoped by profile, not committed plaintext.
  • Never commit a keystore (*.jks/*.keystore), *.p12, or *.mobileprovision, and never put API keys in app.config/app.json — anything in app config ships inside the public bundle. See ../secure-coding/SKILL.md.

EAS Workflows

EAS Workflows are Expo's own CI: YAML in .eas/workflows/. Jobs use pre-packaged types (build, submit, update) and chain via needs: + outputs. Route to the github-actions skill only when the user explicitly wants GH Actions or non-Expo CI.

yaml
# .eas/workflows/release-android.yml — build then submit, chained by needs.
name: Release Android
on:
  push:
    branches: [main]
jobs:
  build:
    type: build
    params:
      platform: android
      profile: production
  submit:
    needs: [build]
    type: submit
    params:
      platform: android
      build_id: ${{ needs.build.outputs.build_id }}

Plan limits (set expectations)

EAS Free: 15 Android + 15 iOS builds/month on the low-priority queue only (peak waits can exceed an hour). High-priority queue needs a paid plan; the Production plan includes 2 build concurrencies, with extra concurrency at $50/concurrency/month, up to 5 extra. If a user complains about build queue waits, the fix is usually the plan, not the config. (Pricing per expo.dev/pricing, verified 2026-06-02; re-check before quoting — Expo adjusts tiers and dollar figures.)

Anti-patterns

Anti-patternDo instead
Editing ios/Info.plist directlyprebuild --clean overwrites it; write a config plugin / withInfoPlist.
Hardcoding runtimeVersion: '1.0.0' because it is simplerit drifts from the binary; updates silently stop matching. Use the fingerprint policy.
Expecting an OTA update to deliver a bumped native depEAS Update is JS-only; native changes need a new eas build.
Telling users to "just refresh" when a published update does not landcheck the channel→branch and exact runtime match first — wrong channel = no delivery.
Testing a custom native module in Expo GoExpo Go can't load arbitrary native code; build a dev client.
Upgrading the SDK and building straight to productionrun expo-doctor + a preview build first; there is no Legacy-Arch fallback to catch a New-Arch-incompatible dep.
Setting newArchEnabled: false to dodge a broken native depthe flag was removed in SDK 55 and the Legacy Architecture is gone; fix or replace the dep.
Committing the keystore so CI can signnever; let EAS manage credentials or use EAS secrets.
Putting the API key in app.config extraapp config ships in the public bundle; use EAS env vars / a backend.
Reaching for GitHub Actions to call eas buildEAS Workflows is the native CI; only reach for github-actions if explicitly required.

Project grounding (02-DOCS + CLAUDE.md)

In a project with a 02-DOCS/ layer (the harness wiki), read 02-DOCS/wiki/stack/expo.md first and record this app's shipping decisions there — managed-vs-bare, runtime-version policy, channel/branch map, SDK/New-Arch status — linked from the root CLAUDE.md ## Knowledge map, bumping its Updated date when a convention changes. No 02-DOCS/? Skip silently. Conventions are recorded, not gated — never block the task on this.

© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 5 other files (scripts, references) in skills/expo of ericrisco/rsc-harness.

  • SKILL.md
  • evals/README.md
  • evals/cases.yaml
  • references/config-plugins.md
  • references/eas-update.md
  • scripts/verify.sh

Open the folder on GitHubat commit e3d5b33

Compare with similar skills

Expo next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Expo compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Expo this skillericrisco/rsc-harness167—~2.9kAutomated safety check: NotesMIT
Screenmapaleqsio/screenmap242—~7.2kAutomated safety check: PassMIT
ThemingCode-with-Beto/skills141—~2.5kAutomated safety check: PassNone
Revyl CLI Auth BypassRevylAI/revyl-cli522—~2.5kAutomated safety check: PassNone
Fishjam React Native Clientsoftware-mansion-labs/skills291—~1.9kAutomated safety check: PassMIT
Oma Mobilefirst-fluke/oh-my-agent1.3k—~1.6kAutomated safety check: PassMIT

Similar skills

  • Screenmap

    aleqsio/screenmap

    Generate a visual navigation map of an Expo / React Native or NativeScript app.

    242 GitHub stars~7.2k tokensUpdated 3 days ago
    MobileAuto-check passed
  • Theming

    Code-with-Beto/skills

    Scaffold a unified, cross-platform color theme system into an Expo Router app.

    141 GitHub stars~2.5k tokensUpdated 2 mo ago
    MobileAuto-check passed
  • Revyl CLI Auth Bypass

    RevylAI/revyl-cli

    Set up test-only auth bypass for Revyl runs across Expo, React Native, native iOS, native Android, and Flutter apps.

    522 GitHub stars~2.5k tokensUpdated today
    MobileAuto-check passed
  • Fishjam React Native Client

    software-mansion-labs/skills

    React Native / Expo SDK for Fishjam — video/audio streaming on iOS and Android.

    291 GitHub stars~1.9k tokensUpdated 10 days ago
    MobileAuto-check passed
  • Oma Mobile

    first-fluke/oh-my-agent

    Mobile specialist for Flutter, React Native, and cross-platform mobile development.

    1.3k GitHub stars~1.6k tokensUpdated today
    MobileAuto-check passed
  • Mobile App

    ww-w-ai/bkit-claude-code

    Mobile app development guide — React Native, Flutter, Expo for cross-platform.

    601 GitHub stars~2.9k tokensUpdated 11 days ago
    MobileAuto-check: notes

More from ericrisco/rsc-harness

All 227 skills in this repo
  • Ab Testing

    ericrisco/rsc-harness

    A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…

    167 GitHub stars~2.4k tokensUpdated today
    Auto-check passed
  • Accessibility

    ericrisco/rsc-harness

    A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…

    167 GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Ads

    ericrisco/rsc-harness

    A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…

    167 GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Agent Eval

    ericrisco/rsc-harness

    A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…

    167 GitHub stars~3.2k tokensUpdated today
    Auto-check passed
  • AI Media

    ericrisco/rsc-harness

    A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…

    167 GitHub stars~3.3k tokensUpdated today
    Auto-check passed
  • Analytics

    ericrisco/rsc-harness

    A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.

    167 GitHub stars~2.8k tokensUpdated today
    Auto-check passed

Categories

Questions about Expo

What does Expo do?

A skill your agent uses when shipping a React Native app with Expo — EAS Build/Submit/Update, eas.json profiles and channels, config plugins, prebuild/CNG, runtime-version policy, OTA updates that…. Expo is an agent skill from ericrisco/rsc-harness.json profiles and channels, config plugins, prebuild/CNG, runtime-version policy, OTA updates that never land, SDK upgrades, the New Architecture.

When should I use Expo?

Expo fits situations like: shipping a React Native app with Expo — EAS Build/Submit/Update; eas.json profiles and channels; runtime-version policy; OTA updates that never land.

How do I install Expo in Claude Code?

Run `npx skills add ericrisco/rsc-harness --skill expo -a claude-code`. Or copy the skill folder (skills/expo in ericrisco/rsc-harness) into .claude/skills/expo in your project. Claude Code loads it when a task matches its description.

How do I install Expo in Codex?

Run `npx skills add ericrisco/rsc-harness --skill expo -a codex`. Or copy the skill folder (skills/expo in ericrisco/rsc-harness) into .agents/skills/expo in your project. Codex loads it when a task matches its description.

Can I use Expo in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ericrisco/rsc-harness --skill expo -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/expo, .gemini/skills/expo, .github/skills/expo and .opencode/skills/expo in your project.

What does Expo need to run?

Going by SKILL.md and its folder, Expo needs a shell for the scripts in its folder and the command-line tools its instructions call (eas and npx). Our summary lists: Node.js; A Bash shell.

Does Expo access the network?

SKILL.md contains no URLs. Its commands use npx, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Expo safe to install?

Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Expo use?

Expo is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Expo use?

About 2.9k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2.5k tokens, read only when the agent opens those files.

What are the alternatives to Expo?

Skills that share tags, products or a category with Expo: Screenmap (aleqsio/screenmap, 242 stars), Theming (Code-with-Beto/skills, 141 stars), Revyl CLI Auth Bypass (RevylAI/revyl-cli, 522 stars) and Fishjam React Native Client (software-mansion-labs/skills, 291 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Expo?

ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 167 GitHub stars. The repository holds 227 skills in this directory. The repository was last updated on October 7, 2026.

Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.