{"id":51544852,"url":"https://github.com/roninforge/roninforge-expo","last_synced_at":"2026-07-09T17:01:08.910Z","repository":{"id":363762429,"uuid":"1242434606","full_name":"RoninForge/roninforge-expo","owner":"RoninForge","description":"Cursor plugin for Expo SDK 55 (New Architecture default, Expo Router 55, Reanimated 4, FlashList 2, React 19). 45 anti-patterns, 10 rules, 5 skills, reviewer agent. Catches SDK 51-54 leftovers that pre-Nov-2024 LLMs still emit.","archived":false,"fork":false,"pushed_at":"2026-06-10T07:44:46.000Z","size":67,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-10T09:21:29.301Z","etag":null,"topics":["ai-coding","code-review","cursor","cursor-ai","cursor-plugin","cursor-rules","expo","expo-router","expo-sdk-55","llm","mdc","mobile","new-architecture","react-native","reanimated","roninforge","typescript"],"latest_commit_sha":null,"homepage":"https://roninforge.org/#plugins","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RoninForge.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-18T12:27:56.000Z","updated_at":"2026-06-10T07:44:50.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/RoninForge/roninforge-expo","commit_stats":null,"previous_names":["roninforge/roninforge-expo"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/RoninForge/roninforge-expo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoninForge%2Froninforge-expo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoninForge%2Froninforge-expo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoninForge%2Froninforge-expo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoninForge%2Froninforge-expo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RoninForge","download_url":"https://codeload.github.com/RoninForge/roninforge-expo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RoninForge%2Froninforge-expo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35306717,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-09T02:00:07.329Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-coding","code-review","cursor","cursor-ai","cursor-plugin","cursor-rules","expo","expo-router","expo-sdk-55","llm","mdc","mobile","new-architecture","react-native","reanimated","roninforge","typescript"],"created_at":"2026-07-09T17:01:07.660Z","updated_at":"2026-07-09T17:01:08.904Z","avatar_url":"https://github.com/RoninForge.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# roninforge-expo\n\nCursor plugin for Expo SDK 55. Catches the SDK 51-54 leftovers that pre-Oct-2024 LLMs still emit when you tell them to build an Expo app.\n\n## Why this exists\n\nExpo SDK 54 (Oct 2025) and SDK 55 (May 2026) reshuffled the canonical stack:\n\n- **Reanimated 4** replaced Reanimated 3. The Babel plugin moved from `react-native-reanimated/plugin` to `react-native-worklets/plugin`.\n- **FlashList 2.0** replaced FlashList 1.x. `estimatedItemSize` is now a no-op.\n- **expo-file-system** swapped its default export. The classic functional API now lives at `expo-file-system/legacy`; the new `File`/`Directory` API is the default.\n- **expo-av** was split into `expo-video` and `expo-audio` and removed from Expo Go.\n- **Legacy Architecture** was removed entirely. `newArchEnabled` and `jsEngine` are noise; Hermes is the only supported engine and bridgeless is the only mode.\n- **Expo Router** ships at major `55` (synced with the SDK number, not as an independent semver). `Stack.Protected` is the canonical auth gate; `router.dismissTo` is the only way to pop multiple screens.\n\nLLM training cutoffs before Oct 2024 still suggest the SDK 51-53 stack. This plugin pins, validates, and migrates.\n\n## Quick install\n\n```sh\ngit clone https://github.com/RoninForge/roninforge-expo ~/.tmp/rf-expo\ncd /path/to/your/project\nmkdir -p .cursor/rules .cursor/skills .cursor/agents\ncp -rn ~/.tmp/rf-expo/rules/*  .cursor/rules/\ncp -rn ~/.tmp/rf-expo/skills/* .cursor/skills/\ncp -rn ~/.tmp/rf-expo/agents/* .cursor/agents/\n```\n\n## What is inside\n\n### Rules (10)\n\n| File | Scope |\n|------|-------|\n| `expo-anti-patterns.mdc` | 45 anti-patterns, severity-grouped (centerpiece) |\n| `expo-router-file-conventions.mdc` | `app/` tree, `_layout.tsx`, `(group)`, `[id]`, `[...rest]`, `+api`, typed routes, `Stack.Protected` |\n| `expo-data-and-storage.mdc` | `expo-secure-store`, `expo-sqlite`, `expo-sqlite/kv-store`, `expo-file-system` new API, env vars |\n| `expo-images-and-media.mdc` | `expo-image` with `contentFit`, `CameraView`, `expo-video`, `expo-audio` |\n| `expo-animations-and-gestures.mdc` | Reanimated 4 worklets, `react-native-worklets/plugin`, `GestureDetector` + `Gesture.Pan` |\n| `expo-lists-and-perf.mdc` | FlashList 2.x without `estimatedItemSize`, `keyExtractor`, `getItemType` |\n| `expo-auth-and-permissions.mdc` | PKCE via `expo-auth-session`, Apple sign-in, per-module permissions, `Stack.Protected` |\n| `expo-build-and-config.mdc` | `app.config.ts`, CNG, `expo-build-properties`, runtimeVersion fingerprint, `eas.json` |\n| `expo-typescript-and-tsconfig.mdc` | `expo/tsconfig.base`, typed routes, `useLocalSearchParams\u003cT\u003e()` |\n| `expo-migration-from-sdk-53.mdc` | Stage-by-stage upgrade from SDK 51-54 to 55 |\n\n### Skills (5)\n\n| Dir | Purpose |\n|-----|---------|\n| `expo-new-route` | Scaffolds a route file under `app/` with typed params |\n| `expo-new-api-route` | Scaffolds a `+api.ts` server route returning `Response` |\n| `expo-new-protected-flow` | Scaffolds the `Stack.Protected` auth pattern |\n| `expo-migrate-from-rn-cli` | Walks SDK 51-54 to 55 with atomic diffs |\n| `expo-validate` | Runs the plugin validator, `expo-doctor`, `tsc --noEmit`, grep audit |\n\n### Agent\n\n`agents/expo-reviewer.md` reviews a codebase against all 45 anti-patterns by file type. Output is CRIT/ERR/WARN/NIT findings with file:line.\n\n## Anti-pattern severity totals\n\n| Severity | Count |\n|----------|------:|\n| CRIT | 4 |\n| ERR | 21 |\n| WARN | 16 |\n| NIT | 4 |\n| **Total** | **45** |\n\n## Pinned versions (SDK 55)\n\nSource of truth: [`expo/sdk-55/packages/expo/bundledNativeModules.json`](https://github.com/expo/expo/blob/sdk-55/packages/expo/bundledNativeModules.json).\n\n| Package | Version |\n|---------|---------|\n| `expo` | `~55.0.0` |\n| `expo-router` | `~55.0.14` |\n| `react` | `19.2.0` |\n| `react-native` | `0.83.6` |\n| `react-native-reanimated` | `~4.2.1` |\n| `react-native-worklets` | `0.7.4` |\n| `react-native-gesture-handler` | `~2.30.0` |\n| `@shopify/flash-list` | `2.0.2` |\n| `expo-image` | `~55.0.10` |\n| `expo-camera` | `~55.0.18` |\n| `expo-video` | `~55.0.17` |\n| `expo-audio` | `~55.0.14` |\n| `expo-file-system` | `~55.0.20` |\n| `expo-secure-store` | `~55.0.14` |\n| `expo-sqlite` | `~55.0.16` |\n| `@expo/vector-icons` | `^15.0.2` |\n| Node | `\u003e= 20.19.4` |\n| TypeScript | `~6.0.3` |\n| eas-cli | `\u003e= 18.13.0` |\n\nUse `~` (tilde), never `^`. Expo's compatibility matrix is minor-version-locked; always run `npx expo install --fix` after a bump.\n\n## Validator\n\n```sh\nbash tests/validation/validate-plugin.sh\n```\n\nChecks:\n\n1. `plugin.json` is valid JSON with required fields\n2. Every `rules/*.mdc` has `---` frontmatter, `description:`, `globs:`\n3. Every `skills/*/SKILL.md` has `name:` matching the directory and `description:`\n4. Every `agents/*.md` has `name:` + `description:`\n5. `correct-sample` is free of all banned patterns (Camera legacy, NavigationContainer, react-native-reanimated/plugin, AsyncStorage, expo-cli, expo-av, FlashList estimatedItemSize, EXPO_PUBLIC_*_SECRET, etc.)\n6. `correct-sample` pins expo `~55`, flash-list `2.x`, reanimated `~4.x`, node `\u003e=20.19.4`\n7. `correct-sample/babel.config.js` uses `react-native-worklets/plugin`, NOT `react-native-reanimated/plugin`\n8. `correct-sample/tsconfig.json` extends `expo/tsconfig.base`\n9. `anti-pattern-sample` contains every required marker (the banned patterns above plus manually-edited `ios/MyApp/Info.plist`)\n10. No em dashes or emojis anywhere in `rules/`, `skills/`, `agents/`, `README.md`\n\n## License\n\nMIT. See [LICENSE](./LICENSE).\n\n## Links\n\n- Expo SDK 55 changelog: https://expo.dev/changelog/sdk-55\n- bundledNativeModules.json (SDK 55): https://github.com/expo/expo/blob/sdk-55/packages/expo/bundledNativeModules.json\n- Expo Router: https://docs.expo.dev/router/introduction/\n- Reanimated 4 migration: https://docs.swmansion.com/react-native-reanimated/docs/guides/migration-from-3.x/\n- FlashList 2 changes: https://shopify.github.io/flash-list/docs/v2-changes\n- expo-file-system new API: https://docs.expo.dev/versions/v55.0.0/sdk/filesystem/\n- expo-auth-session PKCE: https://docs.expo.dev/versions/v55.0.0/sdk/auth-session/\n- CNG: https://docs.expo.dev/workflow/continuous-native-generation/\n- EAS runtimeVersion fingerprint policy: https://docs.expo.dev/eas-update/runtime-versions/\n- RoninForge: https://roninforge.org\n\n\n## More from RoninForge\n\n[RoninForge](https://roninforge.org) builds free tools for developers working with AI coding assistants:\n\n- [LLM API pricing comparison](https://roninforge.org/llm-pricing) - Claude, GPT, Gemini, DeepSeek, Mistral, and Grok token prices side by side, verified against official pricing pages\n- [GitHub Copilot AI Credits calculator](https://roninforge.org/copilot-credits-calculator) - estimate your monthly credit burn under usage-based billing\n- [All Cursor plugins](https://roninforge.org/#plugins)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froninforge%2Froninforge-expo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Froninforge%2Froninforge-expo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Froninforge%2Froninforge-expo/lists"}