--- name: react-native-expert description: Expert guidance for building mobile applications with React Native and Expo. Use when the user asks to create, modify, debug, or architect mobile apps, implement native features (camera, notifications, storage, navigation), set up React Native projects, work with Expo or bare React Native workflows, integrate with device APIs, handle app state management, or optimize mobile performance. Triggers on mobile app development, React Native, Expo, iOS/Android cross-platform development. --- # React Native Mobile Development Expert Expert guidance for building production-quality mobile applications with React Native. ## Project Initialization ### Expo (Recommended for most projects) ```bash npx create-expo-app@latest my-app --template blank-typescript cd my-app npx expo start ``` ### Bare React Native (When native code access required) ```bash npx @react-native-community/cli init MyApp --template react-native-template-typescript cd MyApp npx react-native run-ios # or run-android ``` **Choose Expo when:** rapid prototyping, standard features, OTA updates needed, limited native customization. **Choose Bare when:** custom native modules required, existing native codebase integration, specific native library needs. ## Project Structure ``` src/ ├── app/ # Expo Router screens (if using Expo Router) ├── components/ │ ├── ui/ # Reusable UI primitives │ └── features/ # Feature-specific components ├── hooks/ # Custom hooks ├── services/ # API clients, external services ├── stores/ # State management (Zustand/Redux) ├── utils/ # Helper functions ├── types/ # TypeScript definitions └── constants/ # App-wide constants, theme ``` ## Navigation ### Expo Router (File-based, recommended for Expo) ```typescript // app/_layout.tsx import { Stack } from 'expo-router'; export default function RootLayout() { return ( ); } // app/details/[id].tsx import { useLocalSearchParams } from 'expo-router'; export default function Details() { const { id } = useLocalSearchParams<{ id: string }>(); return Item {id}; } ``` ### React Navigation (Traditional approach) ```typescript import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; type RootStackParamList = { Home: undefined; Details: { id: string }; }; const Stack = createNativeStackNavigator(); function App() { return ( ); } ``` ## State Management ### Zustand (Recommended for simplicity) ```typescript import { create } from 'zustand'; import { persist, createJSONStorage } from 'zustand/middleware'; import AsyncStorage from '@react-native-async-storage/async-storage'; interface AuthStore { user: User | null; token: string | null; setAuth: (user: User, token: string) => void; logout: () => void; } export const useAuthStore = create()( persist( (set) => ({ user: null, token: null, setAuth: (user, token) => set({ user, token }), logout: () => set({ user: null, token: null }), }), { name: 'auth-storage', storage: createJSONStorage(() => AsyncStorage), } ) ); ``` ### TanStack Query (Server state) ```typescript import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; export function useTodos() { return useQuery({ queryKey: ['todos'], queryFn: () => api.getTodos(), }); } export function useCreateTodo() { const queryClient = useQueryClient(); return useMutation({ mutationFn: api.createTodo, onSuccess: () => queryClient.invalidateQueries({ queryKey: ['todos'] }), }); } ``` ## Styling ### NativeWind (Tailwind for React Native) ```bash npx expo install nativewind tailwindcss ``` ```typescript // tailwind.config.js module.exports = { content: ['./app/**/*.{js,tsx}', './src/**/*.{js,tsx}'], presets: [require('nativewind/preset')], theme: { extend: {} }, }; // Component usage import { View, Text } from 'react-native'; export function Card({ title }: { title: string }) { return ( {title} ); } ``` ### StyleSheet (Built-in) ```typescript import { StyleSheet, View, Text } from 'react-native'; const styles = StyleSheet.create({ card: { backgroundColor: '#fff', borderRadius: 12, padding: 16, shadowColor: '#000', shadowOffset: { width: 0, height: 2 }, shadowOpacity: 0.1, shadowRadius: 4, elevation: 3, // Android shadow }, }); ``` ## Common Native Features ### Camera ```typescript import { CameraView, useCameraPermissions } from 'expo-camera'; export function CameraScreen() { const [permission, requestPermission] = useCameraPermissions(); const cameraRef = useRef(null); const takePicture = async () => { const photo = await cameraRef.current?.takePictureAsync(); console.log(photo?.uri); }; if (!permission?.granted) { return