Rork App Launch Crashes & White Screen: Complete Debugging Guide
Your Rork app is crashing at launch. Or worse—it shows a white screen, frozen. You're staring at it, wondering what went wrong. The deadline is tomorrow.
Here's the good news: launch crashes almost always have predictable causes. And once you understand the cause, the fix is straightforward.
The Five Launch Crash Patterns
Your app failure falls into one of these categories:
| Pattern | Symptom | Root Cause | Debug Time |
|---|---|---|---|
| Boot white screen | Splash screen → white screen, frozen | JS bundle not loading | 15-30 min |
| Instant crash | App closes immediately after launch | Native module linking failure | 30-45 min |
| Delayed crash | Works for 3-5 seconds, then crashes | Uncaught Promise rejection | 20-40 min |
| Release build only | Simulator works, production build fails | Code optimization strips needed code | 45-60 min |
| Device-specific | Works on some phones, crashes on others | Memory, API level, or permission mismatch | 30-90 min |
Let's solve each one.
Pattern 1: Boot White Screen (JS Bundle Not Loading)
The Symptom: Splash Screen → White Screen (Frozen)
Your app's splash screen appears, but then nothing. The app is frozen on a blank white screen. This means React Native can't load or execute your JavaScript code.
Diagnostic Steps
Step 1: Check Xcode Console for actual errors
# Open Xcode → Debug → Console
# OR tail logs from terminal while app runs
# For iPhone simulator
xcrun simctl spawn booted log stream --predicate 'process == "YourRorkApp"'
# You should see messages like:
# "Loading JavaScript..."
# "Loaded Bundle" (or error)Look for these error patterns:
❌ Error 1: TypeError: Cannot read property '_callID'
This usually means a React Native dependency is corrupted.
❌ Error 2: could not find file: /main.jsbundle
The JavaScript bundle wasn't packaged into the app.
❌ Error 3: Unexpected token or SyntaxError in code
Your JavaScript has syntax errors that break compilation.
Step 2: Verify Metro Bundler is running
Metro is the JavaScript compiler for React Native. If it doesn't run, your app gets no code to execute.
# Terminal 1: Start Metro (leave this running)
npx react-native start --reset-cache
# You should see output like:
# ✓ Watchman is available
# ✓ To reload the app press r
# ✓ To open developer menu press d
# ✓ Metro Bundler ready
# If it hangs, kill it and retry
pkill -9 node
npx react-native start --reset-cacheStep 3: Check for JavaScript syntax errors
Rork generates valid code, but if you added custom code, syntax errors break the bundle.
// ❌ BAD: Missing closing parenthesis
function loadData() {
const users = fetchUsers(
return users; // SyntaxError - bundle fails to compile
}
// ✓ GOOD: Valid syntax
function loadData() {
const users = fetchUsers();
return users;
}Validate syntax:
# Check all JavaScript files for syntax errors
node -c src/index.js
node -c src/App.js
node -c src/screens/*.js
# If syntax is valid, output is silent
# If there's an error, it prints the problem lineStep 4: Rebuild the bundle
For production/TestFlight builds, you need to generate a bundled version of your code.
# iOS: Generate the bundled JavaScript
npx react-native bundle \
--platform ios \
--dev false \
--entry-file index.js \
--bundle-output ios/main.jsbundle \
--assets-dest ios
# Verify the bundle file exists and has content
ls -lh ios/main.jsbundle
# Should be > 500 KBThe Fix (Checklist)
# White screen resolution sequence
# 1. Kill any existing Metro process
pkill -9 node
sleep 1
# 2. Clean and reinstall dependencies
rm -rf node_modules
npm install
# 3. Start Metro with reset cache
npx react-native start --reset-cache
# 4. In another terminal, rebuild
npx react-native run-ios
# or
npx react-native run-android
# 5. If still broken, clean Xcode caches
rm -rf ~/Library/Developer/Xcode/DerivedData/*
npx react-native run-iosPattern 2: Instant Crash (Native Module Failure)
The Symptom: App closes immediately, no white screen
Unlike the white screen (which is JavaScript-level), instant crashes mean the native code (Swift/Java) failed during initialization. Common causes:
- CocoaPods (iOS) libraries not linked
- Required Info.plist (iOS) keys missing
- Required AndroidManifest.xml (Android) permissions missing
- Native module version mismatch
Diagnostic Steps
iOS: Xcode Organizer Crash Logs
# Open Xcode → Window → Organizer → Crashes
# Look for crashes from latest run
# Common patterns:
# - Exception: NSInvalidArgumentException
# - Reason: "Module not found for XYZ"
# → You need to run 'pod install'
# Or check via command line
log show --predicate 'eventMessage contains[cd] "YourRorkApp"' \
--last 10m | grep -i "crash\|exception\|error"iOS: Verify CocoaPods
# CocoaPods manage native dependencies. If pods aren't installed,
# your app crashes on launch.
cd ios
# Check if Pods exist
ls -la Pods/
# If Pods is missing or outdated:
rm -rf Pods Podfile.lock
pod deintegrate
pod repo update
pod install
# Then rebuild
cd ..
npx react-native run-iosAndroid: adb logcat for details
# Connect Android device or start emulator
adb devices
# Monitor crash logs in real-time
adb logcat | grep -i "crash\|fatal\|exception\|error"
# Look for patterns like:
# AndroidRuntime: FATAL EXCEPTION: main
# java.lang.RuntimeException: Unable to start activity ComponentInfo{...}
# → Indicates AndroidManifest.xml configuration problemThe Fix
iOS:
# Complete iOS reset sequence
cd ios
rm -rf Pods Podfile.lock
# Deintegrate old pods
pod deintegrate
# Update repo and reinstall
pod repo update
pod install
cd ..
# Clean Xcode cache
rm -rf ~/Library/Developer/Xcode/DerivedData/*
# Rebuild
npx react-native run-iosAndroid:
cd android
# Gradle clean removes compiled cache
./gradlew clean
cd ..
# Reinstall JavaScript dependencies
rm -rf node_modules
npm install
# Rebuild APK
npx react-native run-androidVerify Info.plist (iOS) has required keys:
<!-- ios/YourApp/Info.plist -->
<dict>
<!-- Required for networking -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<!-- Required for local network access (iOS 14+) -->
<key>NSLocalNetworkUsageDescription</key>
<string>This app communicates over local network.</string>
<key>NSBonjourServices</key>
<array>
<string>_http._tcp</string>
</array>
</dict>Pattern 3: Delayed Crash (Uncaught Promise Rejection)
The Symptom: App starts, shows home screen, then crashes after 3-5 seconds
The app launches successfully but crashes shortly after. This is almost always because of a Promise that gets rejected, but the error isn't caught.
Example: Your app tries to fetch data from an API, the request fails, and the error crashes the entire app instead of being handled gracefully.
Diagnostic Steps
Step 1: Enable debug mode
# Launch with debugger active
npx react-native run-ios
# Shake device (or press ^⌘Z on simulator)
# Select "Debug"
# This shows a red banner for every uncaught errorStep 2: Add global error handler
The app's top-level file should catch all Promise rejections before they crash:
// index.js (your app entry point)
import React from 'react';
import { AppRegistry } from 'react-native';
import App from './src/App';
// Catch any Promise that rejects without a .catch()
global.onunhandledrejection = (error) => {
console.warn('Unhandled Promise Rejection:', error);
// Don't rethrow—this prevents crash
};
// Also handle errors in useEffect
process.on('unhandledRejection', (reason, promise) => {
console.error('Promise rejected:', reason);
});
AppRegistry.registerComponent('YourRorkApp', () => App);Step 3: Wrap async operations with error handling
// ❌ DANGEROUS: No error handling
export default function App() {
useEffect(() => {
fetchInitialData(); // If this fails, app crashes
}, []);
}
// ✓ SAFE: Errors handled
export default function App() {
useEffect(() => {
fetchInitialData()
.catch((error) => {
console.warn('Data loading failed:', error);
// Continue anyway with fallback data
});
}, []);
}
async function fetchInitialData() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json();
} catch (error) {
throw error; // Re-throw for caller to handle
}
}Step 4: Trace app initialization
Add logging at each step to pinpoint which initialization task crashes:
export default function App() {
const [appReady, setAppReady] = useState(false);
useEffect(() => {
console.log('APP: Starting initialization...');
initializeApp()
.then(() => {
console.log('APP: Initialization complete ✓');
setAppReady(true);
})
.catch((error) => {
console.error('APP: Initialization failed ✗', error);
// Show error screen but don't crash
setAppReady(true);
});
}, []);
if (!appReady) {
return <SplashScreen />;
}
return <MainApp />;
}
async function initializeApp() {
try {
console.log('INIT: Loading database...');
await loadDatabase();
console.log('INIT: Fetching user data...');
await fetchUserData();
console.log('INIT: Preloading assets...');
await preloadAssets();
console.log('INIT: All done!');
return true;
} catch (error) {
console.error('INIT: Failed at step:', error.message);
throw error;
}
}When you run this, console output tells you exactly where the crash happens:
APP: Starting initialization...
INIT: Loading database...
INIT: Fetching user data...
INIT: Failed at step: TypeError: Cannot read property 'id'
↑ This pinpoints the problem
The Fix
# Delayed crash diagnosis
# 1. Add error boundaries (catch rendering errors)
# 2. Add try-catch around all async operations
# 3. Watch console while app runs
npx react-native run-ios 2>&1 | tee debug.log
# 4. Inspect log file for "Error", "FATAL", "undefined"
cat debug.log | grep -i "error\|failed\|cannot"
# 5. Fix the problematic line, rebuild, testPattern 4: Release Build Only Crash
The Symptom: Works perfectly in debug/simulator, but crashes on TestFlight or release APK
This happens when code optimization tools (ProGuard/R8 on Android, Bitcode on iOS) remove code your app actually needs.
The Fix
iOS: Disable Bitcode
# Edit ios/Podfile
open ios/Podfile
# Add this block at the end:
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end
# Reinstall pods
cd ios && pod install && cd ..
# Rebuild
npx react-native run-iosAndroid: Create ProGuard rules
# Create android/app/proguard-rules.pro
cat > android/app/proguard-rules.pro << 'EOF'
# Keep React Native classes
-keep class com.facebook.react.** { *; }
-keep class com.facebook.jni.** { *; }
# Keep native methods
-keepclasseswithmembernames class * {
native <methods>;
}
# Keep your app's classes (CRITICAL)
-keep class net.rorklab.myapp.** { *; }
# Common third-party libraries
-keep class okhttp3.** { *; }
-keep class retrofit2.** { *; }
EOFThen test release build:
# iOS
cd ios
xcodebuild -workspace YourApp.xcworkspace \
-scheme YourApp \
-configuration Release \
-derivedDataPath build
cd ..
# Android
cd android
./gradlew assembleRelease
cd ..
# Install release APK
adb install android/app/build/outputs/apk/release/app-release.apkPattern 5: Device-Specific Crashes
The Symptom: Crashes on old iPhones, newer Android devices, or specific OS versions
# Diagnose device capabilities
adb shell getprop ro.build.version.sdk # API Level
adb shell getprop ro.product.cpu.abilist # CPU type
adb shell cat /proc/meminfo | head -1 # Total memoryMemory optimization:
// ❌ BAD: Loads all images into memory on startup
async function preloadAllImages() {
const allImages = await fetch('/api/images/list');
return Promise.all(
allImages.map(url => Image.prefetch(url)) // ← Can be 500+ MB
);
}
// ✓ GOOD: Lazy load images as needed
async function loadImageOnDemand(url) {
return Image.prefetch(url); // Load one at a time
}Crash Log Decoding
Learn to read actual crash messages:
Example 1: NSInvalidArgumentException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException'
reason: 'Cannot find native module for ImagePicker'
→ Fix: Missing CocoaPods dependency
cd ios && pod install && cd ..Example 2: Module Not Found
Module not found: "react-native-camera" at
Object.<anonymous> (index.android.bundle:1000)
→ Fix: Dependency not linked
npm install react-native-camera
npx react-native link react-native-camera
npx react-native run-androidExample 3: Promise Rejection
Unhandled Promise Rejection: TypeError:
Cannot read property 'result' of undefined
→ Fix: Add null checks
// ❌ UNSAFE
const result = response.data.result.value;
// ✓ SAFE
const result = response?.data?.result?.value ?? null;
if (!result) {
console.warn('No result');
return;
}Pre-Launch Checklist
# Complete Launch Verification Checklist
Basic Functionality:
□ Metro Bundler starts cleanly
□ App launches within 3 seconds
□ No red console errors
□ Home screen displays fully
Platform Testing:
□ iOS Simulator (latest) - clean launch
□ iOS real device (2+ models) - clean launch
□ Android Emulator (2+ API levels) - clean launch
□ Android real device (2+ devices) - clean launch
Performance:
□ Initial memory usage < 50 MB
□ No memory leaks (grows over time)
□ Smooth 60 fps navigation
□ All images load without lag
Configuration:
□ Release builds don't crash
□ Info.plist has all required keys
□ AndroidManifest.xml has all required permissions
□ Code signing certificates valid
□ Bundle ID and Package Name correct
Backend:
□ API endpoints point to production
□ Environment variables set correctly
□ Third-party service keys valid (Firebase, etc.)
□ TestFlight/Play Store beta testedLooking back
Launch crashes feel catastrophic, but they're actually straightforward to diagnose and fix. Follow this order:
- Read the error message (Xcode Console, adb logcat)
- Clear caches (
--reset-cache,pod install,gradle clean) - Enable debugging (Xcode Debugger, React Native Debugger)
- Add error handling (try-catch, .catch(), global handlers)
- Test on multiple devices (simulator, real phone, different OS versions)
Master these skills, and no launch crash will stop you.