React Native Expo Development
Expert guidance for building production-ready mobile applications using TypeScript, React Native, and Expo. This skill provides comprehensive best practices for code architecture, UI development, performance optimization, and cross-platform compatibility.
Instructions
Code Style and Structure
Write concise, technical TypeScript code with accurate examplesUse functional and declarative programming patterns; avoid classesPrefer iteration and modularization over code duplicationUse descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)Structure files in this order: exported component, subcomponents, helpers, static content, typesFollow Expo's official documentation for all setup and configuration: https://docs.expo.dev/Naming Conventions
Use lowercase with dashes for directories (e.g., `components/auth-wizard`)Favor named exports for componentsUse clear, descriptive names that indicate purpose and typeTypeScript Usage
Use TypeScript for all code; prefer interfaces over typesAvoid enums; use maps instead for better type safety and flexibilityUse functional components with TypeScript interfacesEnable strict mode in TypeScript configuration for enhanced type safetyDefine prop interfaces explicitly for all componentsSyntax and Formatting
Use the "function" keyword for pure functionsAvoid unnecessary curly braces in conditionals; use concise syntax for simple statementsWrite declarative JSX that clearly expresses intentUse Prettier for consistent code formatting across the projectKeep components small and focused on single responsibilitiesUI and Styling
Use Expo's built-in components for common UI patterns and layoutsImplement responsive design with Flexbox and `useWindowDimensions` for screen size adjustmentsUse styled-components or Tailwind CSS for component stylingImplement dark mode support using Expo's `useColorScheme` hookEnsure high accessibility (a11y) standards using ARIA roles and native accessibility propsLeverage `react-native-reanimated` and `react-native-gesture-handler` for performant animations and gesturesSafe Area Management
Use `SafeAreaProvider` from `react-native-safe-area-context` to manage safe areas globallyWrap top-level components with `SafeAreaView` to handle notches, status bars, and screen insets on iOS and AndroidUse `SafeAreaScrollView` for scrollable content to respect safe area boundariesAvoid hardcoding padding or margins for safe areas; rely on SafeAreaView and context hooksPerformance Optimization
Minimize use of `useState` and `useEffect`; prefer context and reducers for state managementUse Expo's `AppLoading` and `SplashScreen` for optimized app startup experienceOptimize images: use WebP format where supported, include size data, implement lazy loading with `expo-image`Implement code splitting and lazy loading for non-critical components using React's Suspense and dynamic importsProfile and monitor performance using React Native's built-in tools and Expo's debugging featuresAvoid unnecessary re-renders by memoizing components and using `useMemo` and `useCallback` appropriatelyUse FlatList and SectionList with proper key extraction and item optimization for long listsNavigation
Use `react-navigation` for routing and navigation; follow best practices for stack, tab, and drawer navigatorsLeverage deep linking and universal links for better user engagement and navigation flowUse dynamic routes with `expo-router` for streamlined navigation handlingImplement proper navigation typing for type-safe navigation throughout the appState Management
Use React Context and `useReducer` for managing global stateLeverage `react-query` for data fetching and caching; avoid excessive API callsFor complex state management, consider using Zustand or Redux ToolkitHandle URL search parameters using `expo-linking`Keep state as local as possible; lift only when necessaryError Handling and Validation
Use Zod for runtime validation and error handlingImplement proper error logging using Sentry or similar servicesPrioritize error handling and edge cases: - Handle errors at the beginning of functions
- Use early returns for error conditions to avoid deeply nested if statements
- Avoid unnecessary else statements; use if-return pattern instead
- Implement global error boundaries to catch and handle unexpected errors
Use `expo-error-reporter` for logging and reporting errors in productionProvide user-friendly error messages while logging detailed errors server-sideTesting
Write unit tests using Jest and React Native Testing LibraryImplement integration tests for critical user flows using DetoxUse Expo's testing tools for running tests in different environmentsConsider snapshot testing for components to ensure UI consistencyTest on both iOS and Android platforms regularlyMock native modules appropriately in testsSecurity
Sanitize user inputs to prevent XSS attacksUse `react-native-encrypted-storage` for secure storage of sensitive dataEnsure secure communication with APIs using HTTPS and proper authenticationFollow Expo's Security guidelines: https://docs.expo.dev/guides/security/Never commit API keys or secrets; use environment variables via `expo-constants`Implement proper certificate pinning for sensitive applicationsInternationalization (i18n)
Use `react-native-i18n` or `expo-localization` for internationalization and localizationSupport multiple languages and RTL layoutsEnsure text scaling and font adjustments for accessibilityTest with various locale settings to ensure proper formattingKey Conventions
1. Rely on Expo's managed workflow for streamlined development and deployment
2. Prioritize Mobile Web Vitals (Load Time, Jank, and Responsiveness)
3. Use `expo-constants` for managing environment variables and configuration
4. Use `expo-permissions` to handle device permissions gracefully
5. Implement `expo-updates` for over-the-air (OTA) updates
6. Follow Expo's best practices for app deployment and publishing: https://docs.expo.dev/distribution/introduction/
7. Ensure compatibility with iOS and Android by testing extensively on both platforms
8. Use EAS (Expo Application Services) for building and deploying production apps
9. Keep Expo SDK updated to benefit from latest features and security patches
10. Document platform-specific code and workarounds clearly
Examples
Component Structure Example
```typescript
// components/user-profile/index.tsx
import { View, Text, Image } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
interface UserProfileProps {
userId: string;
onEdit: () => void;
}
export function UserProfile({ userId, onEdit }: UserProfileProps) {
const user = useUser(userId);
if (!user) return <LoadingState />;
return (
<SafeAreaView>
<ProfileHeader user={user} />
<ProfileActions onEdit={onEdit} />
</SafeAreaView>
);
}
function ProfileHeader({ user }: { user: User }) {
return (
<View>
<Image source={{ uri: user.avatar }} />
<Text>{user.name}</Text>
</View>
);
}
```
Error Handling Pattern
```typescript
async function fetchUserData(userId: string) {
if (!userId) {
throw new Error('User ID is required');
}
try {
const response = await api.getUser(userId);
return response.data;
} catch (error) {
logger.error('Failed to fetch user data', { userId, error });
throw new Error('Unable to load user profile');
}
}
```
Constraints
Always prioritize cross-platform compatibility; test on both iOS and AndroidFollow Expo's managed workflow unless ejection is absolutely necessaryEnsure all external dependencies are compatible with ExpoMaintain backward compatibility with supported Expo SDK versionsKeep bundle size optimized; avoid unnecessary dependenciesRespect platform-specific design guidelines (iOS Human Interface Guidelines, Android Material Design)Reference
Expo Documentation: https://docs.expo.dev/React Native Documentation: https://reactnative.dev/Expo Security Guidelines: https://docs.expo.dev/guides/security/Expo Distribution Guide: https://docs.expo.dev/distribution/introduction/