Skip to main content

React Native Code Review Checklist

Rapid-scan checklist for React Native mobile application code reviews.

React Web vs React Native

This checklist focuses on mobile-specific concerns. For common React patterns (hooks, state, performance), also reference React Code Review Checklist.


Security Red Flags - Block PR Immediately

  • Sensitive data in AsyncStorage: Tokens, passwords, PINs stored unencrypted → Use Keychain/Keystore → React Native Security - Secure Storage
  • API keys in source code: Credentials hardcoded in components, constants, or .env files in repo
  • Missing certificate pinning: Production API calls without certificate pinning → React Native Security - Certificate Pinning
  • dangerouslySetInnerHTML in WebView: HTML injection in WebView content
  • Deep links without validation: Opening URLs from Linking.openURL without validation
  • Jailbreak/root detection disabled: Production builds without security checks on compromised devices
  • ProGuard/R8 disabled: Android release builds without code obfuscation
  • Hermes disabled in production: Missing bytecode obfuscation for iOS
  • Insecure HTTP allowed: NSAllowsArbitraryLoads enabled or cleartext traffic permitted
  • Biometric auth bypassed: Fallback authentication without server validation

Common Mistakes

React Native Specific

  • Network requests on main thread (should be async) → React Native Performance
  • Large images not optimized (use FastImage, webp format)
  • FlatList without keyExtractor or improper key values
  • Missing removeClippedSubviews on long FlatLists
  • ScrollView with many children instead of FlatList/SectionList
  • Animated values not using native driver when possible
  • Not using Hermes JavaScript engine (better performance)

Platform-Specific Issues

  • Missing Platform.OS checks for platform-specific code
  • Not using Platform.select for cross-platform values
  • iOS-specific code without Android equivalent (or vice versa)
  • Missing SafeAreaView on iOS (content hidden by notch/home indicator)
  • Not handling Android back button
  • Permission requests without platform-specific handling
  • Navigator mounted inside component that re-renders → React Native Navigation
  • Missing deep link handling
  • No loading states during navigation transitions
  • Navigation state stored in global state (should use navigation state)
  • Passing large objects via navigation params instead of IDs

Hooks & Effects

  • See React Code Review - Hooks for common React hook issues
  • Event listeners not removed on unmount (NetInfo, AppState, keyboard events)
  • BackHandler listener not removed on unmount
  • Not cancelling fetch requests on unmount

State Management

  • Overusing global state for local UI state → React Native Data
  • Not persisting critical state (user preferences, cart, draft data)
  • Storing sensitive data in persisted Redux/Zustand (should use Keychain)
  • Missing offline queue for failed network requests

Watch For - Performance & Mobile-Specific Issues

Performance

  • Long initial load time (> 3 seconds on mid-range devices)
  • Slow FlatList scrolling (not hitting 60fps) → React Native Performance - List Optimization
  • Images not cached (use react-native-fast-image)
  • Missing image size optimization (retina images on low-DPI screens)
  • Animations janky (< 60fps, not using native driver)
  • Large bundle size (> 20MB for Android, > 50MB for iOS)
  • Missing bundle splitting or lazy loading for large apps
  • Memory leaks from retained references or listeners

FlatList Issues

  • Missing getItemLayout for fixed-height items (improves scroll performance)
  • No windowSize optimization (defaults may be too large)
  • Missing removeClippedSubviews={true} for very long lists
  • Re-rendering entire list when data changes (missing proper keyExtractor)
  • Inline functions in renderItem without useCallback

Memory & Leaks

  • High-resolution images loaded for list items
  • Images not released from memory when off-screen
  • Subscriptions to native modules not cleaned up
  • Event emitters not removed on unmount
  • Timers not cleared when component unmounts
  • Large objects held in state unnecessarily

Network

  • No request timeout configured → React Native Data - API Integration
  • Missing retry logic for failed requests
  • Not handling offline scenarios gracefully
  • Fetching large payloads without pagination
  • Missing request/response interceptors for auth tokens
  • No request deduplication

Offline Support

  • No offline persistence for critical data → React Native Data
  • Missing network state detection (NetInfo)
  • No offline queue for mutations
  • Not syncing local changes when back online
  • Missing conflict resolution for offline edits

Platform Differences

  • UI doesn't match platform conventions (Material on iOS, Cupertino on Android)
  • Missing platform-specific navigation patterns (tab bar position)
  • Font rendering differences not accounted for (Android vs iOS)
  • Status bar color not configured per platform
  • Missing Android-specific features (hardware back button handling)

Best Practices - Code Quality

React Native Architecture

  • Functional components with TypeScript → React Native Overview
  • Custom hooks for device APIs (camera, location, permissions)
  • Platform-specific code isolated in separate files (.ios.ts, .android.ts)
  • Shared business logic, platform-specific UI when needed
  • Feature-based folder structure

Performance

  • Hermes enabled for production builds → React Native Overview - Performance
  • FlatList for lists > 10 items
  • Images optimized (webp format, appropriate sizes)
  • react-native-fast-image for network images
  • Native driver for animations (useNativeDriver: true)
  • Code splitting with lazy loading for large features
  • Bundle size monitoring

Security

  • Keychain/Keystore for sensitive data → React Native Security
  • Certificate pinning enabled
  • ProGuard/R8 obfuscation for Android release builds
  • Hermes bytecode for iOS obfuscation
  • Jailbreak/root detection
  • Disable logging in production builds
  • Screen capture prevention for sensitive screens

Data & State

  • React Query for server state (caching, background updates) → React Native Data
  • Zustand for global client state
  • AsyncStorage for non-sensitive persisted data
  • Offline-first architecture for core features
  • Optimistic updates for better UX

UI/UX

  • SafeAreaView on iOS screens
  • Platform-specific designs (Material You on Android, iOS HIG on iOS)
  • Loading states for async operations
  • Error states with retry actions
  • Empty states for no data
  • Pull-to-refresh on lists
  • Haptic feedback for interactions
  • React Navigation (recommended) → React Native Navigation
  • Deep linking configured
  • Loading states during navigation
  • Proper back button handling (Android)
  • Tab bar navigator for bottom navigation
  • Stack navigator for hierarchical navigation

Testing

  • Unit tests for business logic and custom hooks → React Native Testing
  • Integration tests with React Native Testing Library
  • E2E tests with Detox for critical flows
  • Visual regression tests for UI components
  • Test on both platforms (iOS and Android)
  • Test on multiple device sizes

Build Configuration

  • Separate staging and production builds with different bundle IDs
  • Environment-specific configuration (API URLs, keys)
  • Proper versioning (semver)
  • ProGuard rules for third-party libraries
  • Bitcode disabled (deprecated by Apple)
  • App signing configured correctly

Quick Scan Table

CategoryWhat to CheckSeverityReference
SecurityKeychain/Keystore for sensitive dataBlockSecurity
SecurityCertificate pinning enabledBlockSecurity
SecurityNo API keys in source codeBlockSecurity
SecurityProGuard/obfuscation enabledFixSecurity
PerformanceFlatList for long lists (not ScrollView)FixPerformance
PerformanceImages optimized (webp, sized correctly)FixPerformance
PerformanceAnimations use native driverFixPerformance
GOOD:PerformanceHermes enabledReview
PlatformSafeAreaView on iOSFixUI
PlatformAndroid back button handledFixNavigation
GOOD:PlatformPlatform-specific code isolatedReview
HooksEvent listeners cleaned upFixReact Checklist
HooksDependencies complete in useEffectFixReact Checklist
DataOffline support for critical featuresFixData
DataRequest timeouts configuredFixData
GOOD:NavigationDeep linking configuredReview
GOOD:BuildStaging and production builds separatedReview

Legend:

  • Block PR - Security vulnerability or critical mobile-specific bug
  • Fix Before Merge - Performance issue, platform compatibility, or likely bug
  • [GOOD] Review & Discuss - Code quality improvement

Additional Mobile Considerations

Device-Specific Issues

  • Not testing on low-end Android devices (< 2GB RAM)
  • Missing landscape orientation support when required
  • No tablet layout for large screens
  • Different screen densities not handled (mdpi, hdpi, xhdpi, xxhdpi)
  • Notch/Dynamic Island not accounted for (iOS)
  • Foldable device support missing when required (Android)

Permissions

  • Permissions requested without user-facing explanation
  • Missing permission rationale (iOS usage descriptions, Android permission dialogs)
  • Not handling denied permissions gracefully
  • Requesting permissions at app launch instead of when needed
  • Missing permission checks before accessing protected APIs

Native Modules

  • Custom native modules without TypeScript types
  • Bridge calls in tight loops (performance issue)
  • Not handling native module errors
  • Missing null checks for optional native module responses
  • Native module threading issues (calling UI thread from background)

Push Notifications

  • No notification permission request flow
  • Missing notification handler for foreground notifications
  • Deep links from notifications not working
  • Notification data not validated before processing
  • No badge count management

App State Management

  • Not handling app background/foreground transitions
  • Sensitive data visible when app backgrounded (missing blur overlay)
  • Timers not paused when app backgrounded
  • Network requests not cancelled when backgrounded
  • Missing state restoration after app termination

Accessibility

  • Missing accessibility labels on interactive elements
  • No screen reader support (VoiceOver, TalkBack)
  • Minimum touch target size < 44x44 points
  • Missing focus management for keyboard navigation
  • No dynamic type support (font scaling)

Block Checklist - Must Fix Before Merge

  • No sensitive data in AsyncStorage (use Keychain/Keystore)
  • No API keys or secrets in source code
  • Certificate pinning enabled for production
  • ProGuard/R8 enabled for Android release
  • No network calls on main thread
  • Event listeners cleaned up on unmount
  • FlatList used for long lists (not ScrollView)
  • SafeAreaView used on iOS screens
  • Android back button handled properly
  • No infinite loops or memory leaks

Mobile-Specific Testing Checklist

Before approving mobile PRs, verify:

  • Tested on both iOS and Android
  • Tested on multiple screen sizes (small phone, large phone, tablet if applicable)
  • Tested offline behavior
  • Tested slow network (3G simulation)
  • Tested app backgrounding and foregrounding
  • Tested deep links
  • Tested push notifications (if applicable)
  • Tested permission flows (grant and deny scenarios)
  • Checked memory usage (< 200MB for most screens)
  • Checked bundle size impact

React Native Guides:

Cross-Platform:

Process: