A practical guide for building production-ready React Native and Expo applications. Covers UI, animations, state, testing, performance, and deployment.
Consult these resources as needed:
headerLargeTitle, headerBackButtonDisplayMode), links, modals, sheets, context menusexpo-image, safe areas ( contentInsetAdjustmentBehavior), native controls, blur/glass effects, storagememo, bundle analysis, TTI, memory leaks, animation perfuse*Permissions hooks), haptics, notifications, biometricscomponents/ui/, stores/, services/), path aliases, SDK upgrades, EAS build/submit, CI/CD, DOM componentsPurposeUseInstead ofListsFlashList ( @shopify/flash-list) + memo itemsFlatList (no view recycling)Imagesexpo-imageRN <Image> (no cache, no WebP)PressPressable``TouchableOpacity (legacy)Audioexpo-audio``expo-av (deprecated)Videoexpo-video``expo-av (deprecated)AnimationsReanimated 3RN Animated API (limited)GesturesGesture HandlerPanResponder (legacy)Platform checkprocess.env.EXPO_OS``Platform.OSContextReact.use()``React.useContext() (React 18)Safe area scrollcontentInsetAdjustmentBehavior="automatic"``<SafeAreaView>SF Symbolsexpo-image with source="sf:name"``expo-symbols
SituationConsiderLong lists with scroll jankVirtualized list libraries (e.g. FlashList)Want Tailwind-style classesNativeWind v4High-frequency storage readsSync-based storage (e.g. MMKV)New project with ExpoExpo Router over bare React Navigation
State TypeSolutionLocal UI stateuseState / useReducerShared app stateZustand or JotaiServer / async dataReact QueryForm stateReact Hook Form + Zod
PriorityIssueFixCRITICALLong list jankFlashList + memoized itemsCRITICALLarge bundleAvoid barrel imports, enable R8HIGHToo many re-rendersZustand selectors, React CompilerHIGHSlow startupDisable bundle compression, native navMEDIUMAnimation dropsOnly animate transform/ opacity
bash
# 1. Create project
npx create-expo-app@latest my-app --template blank-typescript
cd my-app
# 2. Install Expo Router + core deps
npx expo install expo-router react-native-safe-area-context react-native-screens
# 3. (Optional) Common extras
npx expo install expo-image react-native-reanimated react-native-gesture-handler
Then configure:
package.json: "main": "expo-router/entry"app.json: "scheme": "my-app"App.tsx and index.tsapp/_layout.tsx as root Stack layoutapp/(tabs)/_layout.tsx for tab navigationapp/(tabs)/ (see navigation.md)For web support, also install: npx expo install react-native-web react-dom @expo/metro-runtime
Consult references before writing: when implementing navigation, lists, networking, or project setup, read the matching reference file above for patterns and pitfalls.
Try Expo Go first ( npx expo start). Custom builds ( eas build) only needed when using local Expo modules, Apple targets, or third-party native modules not in Expo Go.
Conditional rendering: use {count > 0 && <Text />} not {count && <Text />} (renders "0").
Animation rule: only animate transform and opacity — GPU-composited, no layout thrash.
Imports: always import directly from source, not barrel files — avoids bundle bloat.
Lists and images: before using FlatList or RN Image, check the Component Preferences table above — FlashList and expo-image are almost always the right choice.
Route files: always use kebab-case, never co-locate components/types/utils in app/.
tsconfig.json path aliases configuredEXPO_PUBLIC_API_URL env var set per environmentGestureHandlerRootView (if using gestures)contentInsetAdjustmentBehavior="automatic" on all scroll viewsFlashList instead of FlatList for lists > 20 items--profile mode, fix frames > 16mssource-map-explorer), no barrel importsFlutter development → see flutter-dev skill.
iOS native (UIKit/SwiftUI) → see ios-application-dev skill.
Android native (Kotlin/Compose) → see android-native-dev skill.
React Native is a trademark of Meta Platforms, Inc. Expo is a trademark of 650 Industries, Inc. All other product names are trademarks of their respective owners.