Test snapshot: 2026-08-09
Project: expo/skills
Repository snapshot: 2,380 stars, 125 forks, last pushed 2026-08-07
License: MIT | Scale: 23 skills
Evidence boundary: L0 static checks, L1 routing tests, and L2 code-output comparisons were completed. This round did not run
npm install, a build, a simulator, or screenshot regression.
The short answer
Expo’s official skills are the easiest of the three mobile-development collections to keep under control. There are only 23 entries, yet they cover Expo Router, data fetching, native modules, EAS builds and submissions, OTA updates, hosting, and observability. More importantly, the repository enforces a 1,024-character description limit and a 500-line body limit in CI.
This review scores the collection 4.1/5. L0 reached 23/23 complete core fields and zero broken links, with every user-facing skill passing the size limits. L1 reached 19/20 top-1 after correcting the ground truth. L2 improved from 10/12 with the bare model to 12/12 with expo-data-fetching, but the two extra points were Expo’s EXPO_PUBLIC_ environment-variable convention and a React Query/SWR prescription—not fixes that the model could not otherwise produce for the three reported bugs.
The collection is worth using, but “official” does not mean “generated code needs no review.” Its most reliable value is bringing Expo/EAS-specific conventions, version boundaries, and service attributes into context. Its clearest gap is the complete absence of freshness metadata such as last_verified or review_by.
Scorecard
| Dimension | Weight | Score | Evidence from this review |
|---|---|---|---|
| Output gain (L2) | 25% | 3.5/5 | A: 10/12, B: 12/12; the delta was framework convention plus prescription |
| Engineering quality (L0) | 20% | 4.5/5 | Zero broken links and hard size limits, but weak provenance metadata |
| Routing accuracy (L1) | 15% | 4.0/5 | 18/20 initially, 19/20 after correcting the ground truth |
| Coverage | 15% | 4.0/5 | Expo/EAS-specific with a higher share of everyday app tasks than Android’s long tail |
| Authority | 10% | 4.5/5 | Maintained by the framework vendor, though not a platform-level authority like Apple or Google |
| Executability | 10% | 4.5/5 | expo-skill-eval points toward simulator and screenshot validation |
| Maintenance | 5% | 4.5/5 | Active pushes and external contributions |
| Weighted total | 100% | 4.1/5 | Install selectively by project |
What is in the collection?
The repository divides the skills into three practical layers.
Expo framework, open source
expo-router, expo-ui, expo-native-ui, expo-data-fetching, expo-dom, expo-module, expo-brownfield, expo-app-clip, expo-dev-client, expo-project-structure, expo-tailwind-setup, expo-upgrade, expo-web-to-native, expo-examples, and expo-migrate-module.
These entries answer implementation questions inside an Expo/React Native project: file-based navigation, native modules, data fetching, Tailwind, Brownfield integration, and SDK upgrades.
EAS services, paid
eas-app-stores, eas-hosting, eas-observe, eas-simulator, eas-update-insights, and eas-workflows.
These entries cover EAS builds, App Store and Google Play submissions, API-route hosting, production observability, cloud simulators, and OTA adoption. Account access, pricing, and hosted-service dependencies are separate engineering decisions.
Internal meta-skills
expo-skill-eval and expo-skill-feedback are maintenance tools rather than everyday application-development skills.
This split has a practical benefit: an agent and a developer can see whether a capability is framework knowledge or a potentially billable EAS service before loading the full body.
How we tested it
To avoid turning GitHub stars into a quality claim, the review has three layers.
L0: Full static audit
harness/l0_static_audit.py checks all 23 SKILL.md files for required fields, relative links, body size, auxiliary references, and provenance fields.
L1: Routing accuracy
The model sees only the name + description for all 23 skills and cannot read their bodies. Twenty prompts cover routing, upgrades, data fetching, EAS releases, simulators, and official examples. We record the top-1 selection.
L2: Expo Router data-fetching A/B test
The fixture is an Expo Router task list with three reported problems: stale responses after rapidly switching tabs, a blank screen offline, and a token stored insecurely. Group A runs without a skill; Group B receives expo-data-fetching; each group runs three times and is graded against 12 static checks.
L3—npm install, a real build, simulator execution, and screenshots—was not run. The fixture also has an inconsistent version combination: expo ~54 is paired with expo-router ~5, while SDK 54 needs its matching Router version checked. L2 therefore measures relative output, not whether the final app builds unchanged.
L0: The strongest size governance of the three collections
The full static result is:
| Metric | Result |
|---|---|
| Complete core fields | 23/23 |
| Broken relative links | 0/23 |
SKILL.md entries over 5,000 tokens | 2/23 |
| No auxiliary documents | 7/23 |
| Resident catalog context | 2,173 tokens |
Total SKILL.md size | 55,662 tokens |
A CI limit beats “please keep it concise”
The repository’s scripts/check-skill-limits.ts defines:
``ts const MAX_DESCRIPTION = 1024; const MAX_BODY_LINES = 500; ``
It also enforces:
- a
Framework (OSS).orEAS service (paid).prefix; EAS service - costs apply.in EAS skill bodies;- a link to
expo.dev/pricing.
The measured result is 100% compliance: the longest description is 996 characters, no user-facing body exceeds 500 lines, and only the two internal meta-skills are exempt from the category prefix.
That explains the size difference. Expo’s 23 skills total 55,662 tokens; the Apple community collection’s 183 skills total 463,390. Expo’s largest user-facing skill is 5,806 tokens, while Apple’s largest single file reaches 15,667. Neither Android nor Apple has an equally hard guard against unbounded body growth.
Paid/free disclosure is a useful mechanism
All six EAS skills carry EAS service (paid)., and their bodies must include a cost callout and pricing link. This is not advertising; it is a boundary around cost and permissions. When an agent recommends eas-hosting, eas-workflows, or eas-simulator, the user knows that accounts, cloud execution, and billing may be involved.
The biggest gap: no freshness metadata
Expo is the weakest of the three collections on provenance fields:
| Field | Android | Apple | Expo |
|---|---|---|---|
author | 100% | 0% | 0% |
license | 100% | 0% | 86% |
updated | 95% | 100% | 0% |
review_by | 0% | 100% | 0% |
allowed-tools | 0% | 100% | 26% |
keywords | 100% | 0% | 0% |
The content repeatedly mentions SDK 55+ and SDK 56, but exposes no last_verified, updated, or review_by. For a fast-moving framework, an agent cannot automatically determine whether the text matches the project’s SDK.
L1: The corrected top-1 result is 19/20
The initial result was 18/20. Review found that one of the two misses was a flawed ground truth, so the more accurate result is 19/20 (95%).
P18: Secure token storage is a real description gap
The expo-data-fetching body contains an Authentication section and explicitly uses expo-secure-store:
``ts getToken: () => SecureStore.getItemAsync(TOKEN_KEY) ``
But its description lists fetch API, React Query, SWR, error handling, caching, offline support, and Router data loaders. It does not mention auth, token, SecureStore, credential, or keychain. Selecting NONE for “Where should I store a token securely?” is therefore reasonable from the catalog alone.
This is not a missing body capability; it is a capability that the description fails to expose. Adding “auth tokens / secure storage / request interceptors” would fix the routing gap.
P19: The simulator miss was actually a ground-truth error
eas-simulator explicitly says not to auto-trigger on macOS for an ordinary local simulator request. It is for cloud, remote, shareable simulators, or hosts without a local simulator.
The test ran on macOS and the prompt only said “I want to run it on a simulator,” with no cloud or remote context. Selecting NONE follows the skill’s own exclusion rule. It should not be scored as a routing failure.
The description is actually the best disambiguation sample in the three reviews: it gives positive scenarios, host conditions, and an explicit negative list.
Classification prefixes: useful for coarse routing, weak inside a cluster
Framework (OSS). and EAS service (paid). help with coarse routing: App Store submissions, EAS workflows, production observation, and OTA adoption can first be narrowed to the EAS cluster.
Inside that cluster the prefix does almost no disambiguation. eas-observe and eas-update-insights share the same opening; the useful terms come later—crashes, TTI, channels, and install counts. The fixed prefix also consumes the most valuable first words in the description.
Keep the commercial attribute, but move it to the end or make it a separate frontmatter field so the first sentence can describe the actual job.
“ANY network request” overpromises
expo-data-fetching says it covers:
debugging ANY network request, API call, or data fetching
That brings it close to eas-hosting for “I want to deploy an API backend.” The more specific “+api.ts handlers” and “eas deploy” terms allowed eas-hosting to win, but the margin is not risk-free. Worse, ANY promises universal network coverage without mentioning secure token storage in the description.
Replace the universal claim with a bounded description such as “fetch/HTTP read and write paths, including cancellation, auth tokens, and caching,” and explicitly state that it does not deploy a backend.
L2: From 10/12 to 12/12, but the increment needs to be separated
| Check | A1 | A2 | A3 | B1 | B2 | B3 |
|---|---|---|---|---|---|---|
Check response.ok/status | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Move tokens to SecureStore | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Stop using AsyncStorage for tokens | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Cancellation and race protection | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
Use EXPO_PUBLIC_ for API URLs | — | — | — | ✓ | ✓ | ✓ |
| Remove hard-coded URLs | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Remove axios | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Render error state in the UI | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Adopt React Query/SWR | — | — | — | ✓ | ✓ | ✓ |
| Avoid full refetch on toggle | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| No hallucinated dependency | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Preserve the TypeScript entry point | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Total | 10/12 | 10/12 | 10/12 | 12/12 | 12/12 | 12/12 |
The bare model fixed all three reported problems
All three A runs handled:
- stale responses by using a monotonic request ID in addition to aborting;
- the offline blank state with offline, error, and empty states, Retry, and pull-to-refresh while preserving old data after a failed refresh;
- insecure token storage by migrating to
expo-secure-store, including a one-time move from AsyncStorage followed by deletion of the plaintext copy.
The general model baseline is therefore already strong for common networking work.
The clean increment: an Expo-specific convention
For C05, the A group scored 0/3 and the B group 3/3 on the EXPO_PUBLIC_ environment-variable prefix. This is an Expo convention, not generic React Native knowledge. It is the cleanest gain in this round: the bare model has little reason to invent it, while the skill states it explicitly.
React Query is a design choice, not the only correct answer
All B runs chose React Query/SWR. All A runs wrote a smaller useTasks.ts using AbortController and a request ID. Both approaches fixed the user’s bugs:
| A: hand-written approach | B: skill-led approach | |
|---|---|---|
| Race handling | AbortController + request ID | query key manages cancellation and caching |
| New dependencies | expo-secure-store | React Query + NetInfo + SecureStore |
| Advantage | Fewer dependencies, smaller diff | Caching, retries, and offline recovery built in |
| Cost | More state logic to maintain | Bundle, configuration, and upgrade cost |
For a small list, the B approach is not automatically better. For an app with multiple queries, caches, and offline flows, the React Query prescription may pay off. The checklist marks B as the winner because it follows the skill’s preferred architecture, not because every project should add the same dependencies.
Progressive disclosure worked in practice
All three B runs reported reading the two files in references/ and correctly rejected expo-router-loaders.md as inapplicable: that reference targets web-only / SDK 55+ work, while the fixture is an SDK 54 native app. This is the first of the three reviews to validate that “thin SKILL.md + deeper references” is not merely a structure—it can guide conditional reading.
The mechanisms worth copying
- CI size limits. A 1,024-character description and 500-line body prevent the catalog from growing without control.
- OSS/paid disclosure. Service attributes are visible before routing and execution.
- Explicit exclusions.
eas-simulatoris a good model, but it should include a fallback when host information is missing. - Progressive disclosure. Keep the trigger file thin and put version-specific material in references.
- Official workflow coverage. Router, EAS workflows, store submissions, and API routes are real development entry points.
Strengths and weaknesses
Strengths
- maintained by the Expo framework vendor, with clearer boundaries than generic React Native prompts;
- a manageable 23-entry catalog with about 2,173 resident tokens;
- the strongest long-term size-governance mechanism across the three collections;
- explicit EAS pricing disclosure, reducing surprise cloud and billing dependencies;
- progressive references were correctly read and rejected by condition in L2;
- external contributions are accepted.
Weaknesses
- no
last_verifiedorreview_by, so SDK freshness cannot be automated; expo-data-fetchingcovers secure token storage in the body but hides it from routing descriptions;- fixed prefixes consume the first words without helping much inside a cluster;
- universal words such as
ANYcreate over-triggering pressure; expo-skill-evalexists, but its run artifacts are not committed for external review;- EAS entries involve accounts, permissions, hosted execution, and billing, so they are not the same kind of dependency as an open-source framework skill.
Who should install it?
Good fit
- teams using Expo Router, EAS Build/Update, or Expo Modules;
- projects standardizing SDK upgrades, data fetching, native modules, and store releases;
- developers who need agents to follow Expo-specific conventions instead of generic React Native patterns;
- teams that can accept EAS account, permission, and pricing boundaries.
Do not install everything by default if
- you are only building a small React Native demo;
- the project is pinned to an older Expo SDK and nobody can verify each version-sensitive entry;
- you do not want to add React Query, NetInfo, or hosted EAS dependencies;
- you need a fully local simulator workflow and accidentally choose
eas-simulator.
A safer adoption workflow
- Choose
expo-router,expo-data-fetching,expo-upgrade, or the relevant EAS skill by task instead of installing all 23. - Record Expo SDK, Router, React Native, Node, and EAS CLI versions; add a
review_bydate to your own fork. - For EAS recommendations, confirm account permissions, billing plan, API tokens, and CI secret placement first.
- Treat bug fixes, React Query adoption, SDK upgrades, and hosting changes as separate diffs.
- Run a reversible fixture and save the prompt, diff, dependency changes, build log, and failure paths.
- Complete
npm install,npx expo doctor, a real build, simulator execution, and core interaction regression before using the result in production.
Expo versus Android and Apple Skills
| Google Android Skills | rshankras Apple Skills | Expo Skills | |
|---|---|---|---|
| Publisher | Google official | Community | Expo official |
| Count | 22 | 183 | 23 |
| Resident catalog cost | About 1,595 tokens | About 9,198 tokens | About 2,173 tokens |
| Largest user-facing file | 9,355 tokens | 15,667 tokens | 5,806 tokens |
| Hard size limit | None | None | Yes (1,024 chars / 500 lines) |
| Freshness metadata | Partial last-updated | 100% review_by | 0% |
| Commercial disclosure | None | None | OSS / paid prefix |
| L1 top-1 | 10/10 recall, 0 false positives | 19/20 | 19/20 after correction |
| L2 A group | 8, 9, 10 | 10, 10, 10 | 10, 10, 10 |
| Main skill gain | Lower variance | Modernization convention | Expo convention + architecture prescription |
All three reviews point to the same conclusion: the bare model baseline is higher than expected. Skills add the most value when they encode private conventions, version gates, service boundaries, and team rules that generic training cannot reliably infer. Quantity is not value; selection and governance are.
Editorial verdict
Expo Skills is worth installing, and it is the least painful of the three collections—but select by task. Its biggest strength is not the number of entries. It is the CI policy that keeps the catalog manageable and the visible distinction between open-source framework knowledge and paid EAS services.
The missing pieces are not more prose. The project needs last_verified, an SDK baseline, and committed eval artifacts that outsiders can reproduce. The most urgent description fix is expo-data-fetching: expose auth tokens, secure storage, cancellation, and interceptors, and narrow the promise made by “ANY network request.”
For users, the safest path is to choose one matching skill, pin the Expo SDK, preserve dependency and permission diffs, and complete a real build before keeping it in the project. For skill authors, the pattern worth copying is hard size limits plus commercial disclosure plus true progressive disclosure.
Evidence boundary: This review uses the 2026-08-09 snapshot. L0, L1, and L2 results come from the local evaluation and published repository material; L1 ground truth was reviewed, while L3 installation, build, simulator, and screenshot regression were not completed. The fixture’s Expo/Router version pairing also needs to be checked in a real project, so the relative comparison is not a production-build guarantee.