| name | debug:react-native |
| description | Debug React Native issues systematically. Use when encountering native module errors like "Native module cannot be null", Metro bundler issues including port conflicts and cache corruption, platform-specific build failures for iOS CocoaPods or Android Gradle, bridge communication problems, Hermes engine bytecode compilation failures, red screen fatal errors, or New Architecture migration issues with TurboModules and Fabric renderer. |
React Native Debugging Guide
You are an expert React Native debugger. When the user encounters React Native issues, follow this systematic four-phase approach to identify, diagnose, and resolve the problem efficiently.
Common Error Patterns
Red Screen Errors (Fatal Errors)
- "Unable to load script": Metro bundler connection issues
- "Invariant Violation": React component lifecycle or rendering errors
- "Module not found": Missing or incorrectly linked dependencies
- "Native module cannot be null": Native module linking failures
- "Text strings must be rendered within a component": JSX structure errors
Yellow Box Warnings
- Deprecation warnings for outdated APIs
- Performance warnings (excessive re-renders)
- Unhandled promise rejections
- Console.warn statements
Metro Bundler Issues
- Port 8081 already in use
- Cache corruption causing stale bundles
- Watchman file watching limits exceeded (EMFILE errors)
- Symlink resolution failures
- Module resolution failures
Native Module Linking Errors
- "RCTBridge required dispatch_sync to load" (iOS)
- "Native module XYZ tried to override" conflicts
- CocoaPods installation failures
- Gradle build failures
- Auto-linking not working properly
Bridge Communication Failures
- Serialization errors for complex objects
- Async bridge message queue overflow
- Threading violations (UI updates from background thread)
- Turbo Modules migration issues (New Architecture)
iOS-Specific Build Failures
- Xcode version incompatibility
- CocoaPods cache corruption
- Provisioning profile issues
- Bitcode compilation errors
- M1/M2 architecture issues (Rosetta)
Android-Specific Build Failures
- Gradle version mismatches
- Android SDK path not configured
- NDK version conflicts
- R8/ProGuard minification errors
- MultiDex issues
Hermes Engine Issues
- Bytecode compilation failures
- Incompatible native modules with Hermes
- Source map issues for stack traces
- Memory leaks specific to Hermes
Debugging Tools
React Native DevTools (Primary - RN 0.76+)
The default debugging tool for React Native. Access via Dev Menu or press "j" from CLI.
- Console panel for JavaScript logs
- React DevTools integration for component inspection
- Network inspection
- Performance profiling
Flipper (Comprehensive Desktop Debugger)
Meta's desktop debugging platform with plugin architecture:
- Layout Inspector: Visualize component hierarchies
- Network Inspector: Monitor API requests/responses
- Database Browser: View AsyncStorage, SQLite
- Log Viewer: Centralized JavaScript and native logs
- React DevTools Integration: Inspect component trees and hooks
- Hermes Debugger: Debug Hermes bytecode
Reactotron (State Management Focus)
Free, open-source desktop app by Infinite Red:
- Redux/MobX state tracking
- API request/response logging
- Custom command execution
- Benchmark timing
- Error stack traces
React Native Debugger (All-in-One)
Combines multiple debugging features:
- Chrome DevTools integration
- React DevTools
- Redux DevTools
- Network inspection
Native IDE Tools
- Xcode: iOS crash logs, memory profiler, Instruments
- Android Studio: Logcat, Layout Inspector, Profiler, Memory Analyzer
Console and Logging
console.log(), console.warn(), console.error()
- LogBox for structured error/warning display
- Remote debugging via Chrome DevTools
- Structured logging with severity levels
The Four Phases of React Native Debugging
Phase 1: Information Gathering
Before attempting any fixes, systematically collect diagnostic information:
npx react-native doctor
npx react-native info
node --version
npm --version
lsof -i :8081
netstat -ano | findstr :8081
watchman version
watchman watch-list
pod --version
cd ios && pod outdated
cd android && ./gradlew --version
echo $ANDROID_HOME
Ask the user:
- What is the exact error message (copy full stack trace)?
- When did the error start occurring?
- Did you recently update any dependencies or React Native version?
- Does the error occur on iOS, Android, or both?
- Is this a development build or production build?
- Are you using Expo or bare React Native?
- Is Hermes enabled?
Phase 2: Error Classification and Diagnosis
Classify the error into one of these categories:
JavaScript Errors
Symptoms: Red screen with JS stack trace, errors in console
Diagnosis:
npx eslint src/
npx tsc --noEmit
npx madge --circular src/
Build/Compilation Errors
Symptoms: Build fails before app launches
Diagnosis:
cd ios && xcodebuild clean
cd ios && pod deintegrate && pod install
cd android && ./gradlew clean
cd android && ./gradlew --refresh-dependencies
Runtime/Native Errors
Symptoms: Crash after launch, native stack trace
Diagnosis:
adb logcat *:E | grep -E "(ReactNative|RN|React)"
Metro/Bundler Errors
Symptoms: "Unable to load script", bundling failures
Diagnosis:
ps aux | grep metro
ls -la $TMPDIR/metro-*
ls -la node_modules/.cache/
Dependency/Linking Errors
Symptoms: "Module not found", "Native module cannot be null"
Diagnosis:
npm ls
npx react-native link
npx react-native config
Phase 3: Resolution Strategies
Apply fixes based on error classification:
The Nuclear Option (Clean Everything)
When nothing else works, perform a complete clean:
lsof -ti:8081 | xargs kill -9
rm -rf node_modules
rm -rf $TMPDIR/react-*
rm -rf $TMPDIR/metro-*
rm -rf $TMPDIR/haste-map-*
watchman watch-del-all
cd ios
rm -rf Pods
rm -rf ~/Library/Caches/CocoaPods
rm -rf ~/Library/Developer/Xcode/DerivedData
pod cache clean --all
pod deintegrate
pod setup
pod install
cd ..
cd android
./gradlew clean
rm -rf .gradle
rm -rf app/build
rm -rf ~/.gradle/caches
cd ..
npm cache clean --force
npm install
npx react-native start --reset-cache
npx react-native run-ios
Metro Bundler Fixes
npx react-native start --reset-cache
npx react-native start --port 8082
lsof -ti:8081 | xargs kill -9
watchman watch-del-all
watchman shutdown-server
echo kern.maxfiles=10485760 | sudo tee -a /etc/sysctl.conf
echo kern.maxfilesperproc=1048576 | sudo tee -a /etc/sysctl.conf
sudo sysctl -w kern.maxfiles=10485760
sudo sysctl -w kern.maxfilesperproc=1048576
ulimit -n 65536
iOS-Specific Fixes
cd ios
pod deintegrate
pod cache clean --all
rm Podfile.lock
pod install --repo-update
cd ..
cd ios
xcodebuild clean -workspace YourApp.xcworkspace -scheme YourApp
cd ..
arch -x86_64 pod install
xcrun simctl shutdown all
xcrun simctl erase all
Android-Specific Fixes
export ANDROID_HOME=~/Library/Android/sdk
export ANDROID_HOME=~/Android/Sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
cd android
./gradlew clean
./gradlew assembleDebug --stacktrace
cd ..
cd android
rm -rf .gradle
./gradlew wrapper --gradle-version=8.3
cd ..
yes | sdkmanager --licenses
adb kill-server
adb start-server
adb devices
Native Module Linking Fixes
cd ios && pod install && cd ..
npx react-native run-ios
npx react-native link <package-name>
npx react-native config
cd android && ./gradlew clean && cd ..
cd ios && pod install && cd ..
Hermes Engine Fixes
cd android && ./gradlew clean && cd ..
cd ios
pod deintegrate
pod install
cd ..
Dependency Conflict Resolution
npm ls <package-name>
npm install
yarn install
npm dedupe
Phase 4: Verification and Prevention
After applying fixes, verify the solution:
npx react-native doctor
npx react-native start --reset-cache
npx react-native run-ios
npx react-native run-android
npm test
npx tsc --noEmit
npx eslint src/ --ext .js,.jsx,.ts,.tsx
Prevention strategies:
- Lock dependency versions in package.json
- Use exact versions for native modules
- Keep React Native version updated (within major versions)
- Maintain consistent node_modules across team (use lockfiles)
- Document native configuration changes
- Use CI/CD to catch build issues early
- Enable error boundaries in production
- Implement crash reporting (Sentry, Crashlytics)
Quick Reference Commands
npx react-native doctor
npx react-native info
npx react-native start --reset-cache
npx react-native run-ios
npx react-native run-ios --simulator="iPhone 15 Pro"
npx react-native run-android
npx react-native run-android --deviceId=<device-id>
cd ios && pod install
cd ios && pod update
cd ios && pod deintegrate && pod install
xcodebuild clean -workspace ios/YourApp.xcworkspace -scheme YourApp
cd android && ./gradlew clean
cd android && ./gradlew assembleDebug --stacktrace
cd android && ./gradlew assembleRelease
adb logcat *:E
adb reverse tcp:8081 tcp:8081
lsof -ti:8081 | xargs kill -9
watchman watch-del-all
watchman shutdown-server
rm -rf node_modules
rm -rf $TMPDIR/react-*
rm -rf $TMPDIR/metro-*
rm -rf ios/Pods
rm -rf android/.gradle
rm -rf android/app/build
npm cache clean --force
yarn cache clean
npm install
yarn install
npx react-native log-ios
npx react-native log-android
adb shell input keyevent 82
cd android && ./gradlew bundleRelease
cd ios && xcodebuild -workspace YourApp.xcworkspace -scheme YourApp -configuration Release archive
Platform-Specific Debugging
iOS Debugging Checklist
- Open Xcode and check Issue Navigator (Cmd+5)
- Check Console output in Debug area (Cmd+Shift+C)
- Verify Signing & Capabilities settings
- Check Podfile and Podfile.lock for version mismatches
- Review build phases and linked frameworks
- Use Instruments for memory/CPU profiling
- Check device logs: Window > Devices and Simulators
Android Debugging Checklist
- Open Android Studio and check Build output
- Check Logcat for errors: View > Tool Windows > Logcat
- Verify build.gradle dependencies and versions
- Check AndroidManifest.xml for permissions
- Review ProGuard rules if using minification
- Use Android Profiler for performance issues
- Check
adb devices for device connectivity
New Architecture (Fabric + TurboModules)
If using React Native New Architecture:
newArchEnabled=true
ENV['RCT_NEW_ARCH_ENABLED'] = '1'
cd ios && pod install
cd android && ./gradlew clean
Error Handling Best Practices
import React, { Component, ErrorInfo, ReactNode } from 'react';
interface Props {
children: ReactNode;
fallback?: ReactNode;
}
interface State {
hasError: boolean;
error?: Error;
}
class ErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error: Error): State {
return { hasError: true, error };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
console.error('Error caught by boundary:', error, errorInfo);
}
render() {
if (this.state.hasError) {
return this.props.fallback || <FallbackComponent error={this.state.error} />;
}
return this.props.children;
}
}
const fetchData = async () => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Fetch error:', error);
throw error;
}
};
Debugging Workflow Summary
- Gather Information: Run
npx react-native doctor, collect error messages, identify platform
- Classify Error: JavaScript, Build, Runtime, Metro, or Dependency issue
- Apply Targeted Fix: Use platform-specific commands based on classification
- Verify Fix: Test on both platforms, run tests, check for regressions
- Document: Note what caused the issue and how it was resolved
Remember: Most React Native issues can be resolved by clearing caches and rebuilding. When in doubt, perform the "nuclear option" clean and rebuild.