# react-native-dev

> A Claude Code skill from MiniMax-AI's skills repo for React Native and Expo development — FlashList over FlatList, expo-image over RN Image, Reanimated 3 over the legacy Animated API, NativeWind for Tailwind-style styling, Zustand or Jotai for state, React Query for data, EAS for build and submit.

**Use case**: Build a React Native + Expo app on the modern stack — Expo Router, FlashList, Reanimated 3, NativeWind — without falling back to deprecated APIs the older tutorials still teach

**Canonical URL**: https://agentcookbooks.com/skills/react-native-dev/

**Topics**: claude-code, skills, mobile

**Trigger phrases**: "scaffold an Expo app", "fix React Native list jank", "Reanimated 3 gesture"

**Source**: [MiniMax-AI](https://github.com/MiniMax-AI/skills/tree/main/skills/react-native-dev)

**License**: MIT

---

## What it does

`react-native-dev` is the React Native + Expo skill in [MiniMax-AI's skills repo](https://github.com/MiniMax-AI/skills) — a guide that opens with strong opinions about which RN APIs are still load-bearing and which aren't. The component-preference table is the wedge: `FlashList` (`@shopify/flash-list`) over `FlatList` (no view recycling), `expo-image` over RN `<Image>` (no cache, no WebP), `Pressable` over `TouchableOpacity` (legacy), `expo-audio` and `expo-video` over deprecated `expo-av`, Reanimated 3 over RN's old Animated API, Gesture Handler over `PanResponder`, `process.env.EXPO_OS` over `Platform.OS`, `React.use()` over `useContext()`, `contentInsetAdjustmentBehavior="automatic"` over `<SafeAreaView>`, SF Symbols via `expo-image` source `"sf:name"` over `expo-symbols`. That table is the spine of every later decision.

State splits cleanly across four tools: `useState` / `useReducer` for local UI state, Zustand or Jotai for shared app state, React Query for server / async data, React Hook Form + Zod for form state. Performance priorities run a five-row ladder — CRITICAL: long list jank → `FlashList` + memoized items, large bundle → avoid barrel imports, enable R8; HIGH: re-renders → Zustand selectors, React Compiler; slow startup → disable bundle compression, native nav; MEDIUM: animation drops → only animate `transform` and `opacity`.

The new-project init script lays out the modern Expo Router scaffold: `npx create-expo-app@latest --template blank-typescript`, then `expo-router` + `react-native-safe-area-context` + `react-native-screens`, then optional `expo-image` + `react-native-reanimated` + `react-native-gesture-handler`, then `app/_layout.tsx` as the root Stack and `app/(tabs)/_layout.tsx` for tab navigation. Reference files cover navigation (Expo Router Stack/Tabs/NativeTabs, sheets, modals, context menus), components (FlashList patterns, expo-image, safe areas, native controls, blur/glass), styling (StyleSheet + NativeWind/Tailwind, dark mode), animations (Reanimated 3 entering/exiting, shared values, gestures, scroll-driven), state (Zustand selectors, Jotai atoms, React Query optimistic updates), forms (RHF + Zod multi-step, dynamic arrays), networking (fetch wrapper, optimistic updates, offline, webhooks), performance (FlashList + memo, bundle analysis, TTI, memory leaks), testing (Jest, RNTL, Maestro E2E), native capabilities (camera, location, permission hooks, haptics, notifications, biometrics), and engineering (project layout, path aliases, SDK upgrades, EAS build/submit, CI/CD, DOM components).

## When to use it

- Starting a new React Native + Expo app where you want Expo Router, FlashList, Reanimated 3, and NativeWind as the defaults from line one
- Migrating an older RN project off deprecated APIs (`expo-av` → `expo-audio` / `expo-video`, `TouchableOpacity` → `Pressable`, RN Animated → Reanimated 3)
- Fixing list jank on a long virtualized list — the skill's `FlashList` + memoized items + `getItemType` pattern is the standard fix
- Setting up EAS build and submit, EAS Update for OTA, and CI/CD around them
- Implementing a native capability (camera, location, biometrics, notifications) with the `use*Permissions` hooks pattern

When *not* to reach for it:

- Native-only Android (`android-native-dev`) or iOS (`ios-application-dev`) — those skills give you platform HIG/Material conformance you don't get cross-platform
- Bare React Native without Expo where Expo Router migration is off the table — the skill's defaults skew Expo
- React Native macOS or Windows — the skill is mobile-first
- Game UI built on a custom Skia or WebGL canvas — the skill is component-tree-shaped

## Install

From [MiniMax-AI/skills](https://github.com/MiniMax-AI/skills) at `skills/react-native-dev/`. Drop into `~/.claude/skills/react-native-dev/`. Plugin marketplace install: `claude plugin marketplace add https://github.com/MiniMax-AI/skills` then `claude plugin install minimax-skills`.

The toolchain expectations live outside the skill: Node 20+, an Expo account for EAS, Xcode + Android Studio for local simulators when not using Expo Go, an EAS plan for build/submit when shipping to stores.

## What a session looks like

1. **Component pick.** Skill consults the preference table and picks `FlashList` (not `FlatList`), `expo-image` (not RN `<Image>`), `Pressable` (not `TouchableOpacity`).
2. **State shape decision.** Local UI state stays `useState`. Shared app state goes to Zustand (selectors) or Jotai (atoms). Server data goes to React Query with optimistic updates. Forms get RHF + Zod.
3. **Project init (if new).** Runs the modern Expo Router scaffold — `create-expo-app` blank-typescript template, `expo-router` + safe-area + screens, sets `"main": "expo-router/entry"` in `package.json`, adds `"scheme"` in `app.json`, deletes `App.tsx` + `index.ts`, creates `app/_layout.tsx` as the root Stack, `app/(tabs)/_layout.tsx` for tab nav.
4. **List + image pass.** Long lists use `FlashList` with memoized items and `getItemType`. Images use `expo-image` with `cachePolicy`, `placeholder`, and `transition` props.
5. **Animation pass.** Reanimated 3 with shared values and entering/exiting transitions. Only animate `transform` and `opacity` — GPU-composited, no layout thrash.
6. **Native capabilities pass (if needed).** `usePermissions` hooks for camera, location, notifications, biometrics — request in-context, not at launch.
7. **Build + submit.** EAS configures the build profile (`eas build --profile production`), then `eas submit` to App Store and Play Store. EAS Update handles OTA.
8. **Performance pass (if needed).** Profile, look at the priority ladder, fix the topmost CRITICAL item first.

The discipline that makes it work: the strong defaults. The skill rejects deprecated APIs by name, which short-circuits a class of "this works in the old RN tutorial I'm reading" pull requests that ship on stale primitives.

## Receipts

_TODO — to be filled in from a real session. Once the skill has been pointed at a real React Native + Expo project, this section will capture: whether the FlashList migration eliminated long-list jank measurably (DevTools timeline before/after), whether the Reanimated 3 entering/exiting transitions held up at 60 fps on a low-end Android device (most common failure mode: animating layout-affecting properties instead of `transform`/`opacity`), and whether the EAS build profile produced a working production binary on first run._

## Source and attribution

From [MiniMax-AI's skills repository](https://github.com/MiniMax-AI/skills/tree/main/skills/react-native-dev), an MIT-licensed skill collection. The skill credits `expo/skills` by Expo as a source for native UI, navigation, and animation patterns, alongside Expo and React Native official documentation.

License: MIT.

The wedge over a generic "React Native dev" agent: a preference table that names deprecated APIs and replaces them by default. The five-row performance ladder gives the agent a way to pick the right fix order without trial-and-error — long-list jank gets `FlashList`, large bundle gets barrel-import audit + R8, slow startup gets bundle compression off + native nav, animation drops get `transform`/`opacity`-only.