Org Skills

react-native-architecture

Architect-level guidance for React Native apps — Expo vs bare workflow, New Architecture (Fabric/TurboModules), navigation (Expo Router / React Navigation), state and offline-first data, native module strategy, monorepo sharing with web, theming, and release engineering with EAS.

Download .zip Raw Source
When agents use itUse this whenever the user is starting or restructuring a React Native / Expo project, choosing libraries for navigation, storage, or networking, deciding whether to write a native module, asking about code sharing between React Native and React web, or asking how to organise a mobile codebase. Also apply it when reviewing React Native code for architectural issues.

Install

Copilot (VS Code, Visual Studio, Copilot CLI and github.com) reads skills from the repository — commit them so the whole team gets them.

npx skills add AGCO-Global/org-skills --skill react-native-architecture -a github-copilot
# or with the org installer (adds .github/skills/react-native-architecture):
npx -y github:AGCO-Global/org-skills add skill react-native-architecture

Uses the open skills CLI. Works with Claude Code, Codex, Cursor, Copilot, Gemini CLI, OpenCode, Windsurf and 60+ others — it asks which agent to install into.

npx skills add AGCO-Global/org-skills --skill react-native-architecture
# user-level instead of project-level:
npx skills add AGCO-Global/org-skills --skill react-native-architecture -g

Installs the frontend-react-native-skills plugin, which bundles all Frontend / React Native skills and keeps them updated.

/plugin marketplace add AGCO-Global/org-skills
/plugin install frontend-react-native-skills@org-skills
# or just this skill, in this repository:
npx skills add AGCO-Global/org-skills --skill react-native-architecture -a claude-code

Use Download .zip above, then upload it under Customize → Skills → Upload skill. Team and Enterprise admins can sync this repo as a plugin marketplace instead.

Installs into .agents/skills/, which Codex reads.

npx skills add AGCO-Global/org-skills --skill react-native-architecture -a codex

Installs into Cursor's skills folder.

npx skills add AGCO-Global/org-skills --skill react-native-architecture -a cursor

Installs into Gemini CLI's skills folder.

npx skills add AGCO-Global/org-skills --skill react-native-architecture -a gemini-cli

Any tool with rules, instructions or custom prompts: use Copy SKILL.md above and paste it in. It is plain Markdown.

Commands use your normal git sign-in to GitHub, so they work while the repository is private. Node.js 20+ required.

Skill contents

React Native Architecture

Mobile is a different discipline from web: binaries ship through app stores, users are offline, devices are slow, and mistakes take a week to roll back. Design for that.

1. Platform decisions (write them into ARCHITECTURE.md)

Decision Default Change when
Workflow Expo (managed, with expo-dev-client and config plugins) You must ship a native SDK with no config plugin and can't write one → bare, but keep expo modules. "Ejecting" is rarely justified now.
Architecture New Architecture enabled (Fabric + TurboModules, bridgeless) Only a legacy dependency blocks it — then plan the migration, don't disable forever.
JS engine Hermes Never Jsc.
Navigation Expo Router (file-based, deep links for free) Existing large React Navigation codebase → stay on React Navigation v7.
Styling StyleSheet + a token file, or NativeWind if the team is Tailwind-fluent Design system requires runtime theming across many brands → Tamagui / Unistyles.
Language TypeScript strict Never.
Package manager pnpm with node-linker=hoisted (RN tooling needs hoisting) Yarn in existing monorepo.
Builds/updates EAS Build + EAS Update Enterprise CI requirement → Fastlane + self-hosted, still with Expo modules.

2. Folder structure

Same feature-first principle as React web, with mobile-specific additions:

src/
├── app/                # Expo Router routes only — thin files that render feature screens
│   ├── (auth)/
│   ├── (tabs)/
│   └── _layout.tsx
├── features/<feature>/ # screens/, components/, hooks/, api/, model/, index.ts
├── shared/
│   ├── ui/             # primitives; every one supports light/dark and dynamic type
│   ├── lib/            # api client, storage, analytics, logger, permissions
│   ├── hooks/
│   └── theme/          # tokens: colors, spacing, typography, radii
├── native/             # local Expo modules / TurboModules (Swift/Kotlin) with TS bindings
└── assets/

Rules:

  • Route files in app/ contain no business logic; they import a screen from a feature. Keeps routes testable and the router swappable.
  • Platform forks via Component.ios.tsx / Component.android.tsx only for real divergence; prefer Platform.select inside one file for small differences.
  • shared/ui never imports from features/.

3. Navigation

  • Group routes by auth state: (auth) and (app) groups with a root _layout.tsx that redirects based on session.
  • Typed routes on (experiments.typedRoutes) so router.push params are checked.
  • Deep links and universal links configured from day one (scheme, associatedDomains, intentFilters). Retrofitting is painful.
  • Modals as route groups ((modals)), not component state — they need to be deep-linkable and back-button aware.
  • Keep tab bars to ≤ 5; nest stacks inside tabs, not tabs inside stacks.

4. State and data — offline first

Mobile networks fail constantly. The architecture must assume it:

Kind Tool
Server data TanStack Query with persistQueryClient to MMKV and networkMode: 'offlineFirst'
Mutations while offline Query mutation queue + onlineManager; or a dedicated outbox table for critical writes
Key-value (tokens, settings) MMKV (react-native-mmkv) — synchronous, fast. Never AsyncStorage for hot paths.
Secrets expo-secure-store (Keychain / Keystore) — tokens go here, not MMKV
Relational / large local data Expo SQLite (with Drizzle) or WatermelonDB for sync-heavy apps
Client state Zustand with MMKV persistence
Forms React Hook Form + Zod

Design the sync story explicitly: last-write-wins vs server-authoritative vs CRDT. Document it. Show the user the conflict case before they pick.

5. Native modules — when and how

Decide in this order:

  1. Does an Expo SDK module exist? Use it (expo-camera, expo-location, expo-notifications…). They have config plugins and New Architecture support.
  2. Does a well-maintained community module exist with a config plugin? Check New Architecture support, last release date, open issues.
  3. Write a local Expo Module (npx create-expo-module --local) in Swift/Kotlin. Small, typed, no bridge boilerplate. This is the default for custom native code.
  4. TurboModule / Fabric component by hand only for performance-critical rendering or when integrating an existing large native codebase.

Never patch node_modules without patch-package and a tracking issue. Never run expo prebuild output into git unless you have fully committed to the bare workflow.

6. Sharing code with web

  • Monorepo (Turborepo/Nx): apps/mobile, apps/web, packages/core (domain logic, API client, Zod schemas, query hooks), packages/ui (platform-agnostic primitives only if genuinely shared).
  • Share logic, not screens. Attempts to share full UI via react-native-web succeed for simple apps and fight you for complex ones; be honest about that.
  • packages/core has no react-native imports. Enforce with ESLint.

7. Theming, accessibility, i18n — built in, not bolted on

  • Tokens in shared/theme; components read via a useTheme() hook; support useColorScheme() from day one.
  • Respect Dynamic Type: use allowFontScaling defaults, test at 200%.
  • Every touchable has accessibilityRole, accessibilityLabel; hit targets ≥ 44×44.
  • i18n via i18next + expo-localization; no hard-coded strings in screens; RTL tested with I18nManager.forceRTL in dev.

8. Observability and quality gates

  • Crash reporting (Sentry) with source maps uploaded per build; wrap the root in an error boundary that shows a designed screen and offers "reload".
  • Performance monitoring on cold start, screen TTI, and JS thread FPS (see react-native-performance skill).
  • Feature flags from a remote config so risky features can be killed without a store release.
  • expo-doctor, tsc, ESLint (eslint-plugin-react-native, eslint-plugin-react-hooks), and Jest run in CI on every PR; EAS Build preview per PR.

9. Release engineering

  • Semantic versioning for version; auto-increment buildNumber/versionCode in EAS.
  • Channels: development (dev client), preview (internal testers), production. EAS Update for JS-only fixes; native changes require a store build — teach the team which is which.
  • Runtime version policy appVersion so updates never load against an incompatible native binary.
  • Staged rollout (Play Console %) and phased release (App Store) always on for production.
  • Keep a RELEASE.md runbook: who bumps, how to roll back an update (eas update --republish), how to hotfix.

Anti-patterns to flag

  • AsyncStorage for tokens or hot reads.
  • Business logic in route files or in _layout.tsx.
  • Dimensions.get('window') at module scope (breaks rotation/foldables); use useWindowDimensions.
  • Inline require('./img.png') scattered everywhere — centralise assets.
  • Disabling the New Architecture "for now" without a dated migration ticket.
  • Fetching without offline handling and calling it done.
  • Copying web components into RN and wrapping them in View without redesigning for touch.