React Native Android App Crashes Immediately on Open (Hermes / ProGuard)
An Android app that crashes the instant it opens, but only in release builds (never in debug), points strongly at ProGuard/R8 code shrinking removing or renaming something the app actually needs at runtime — most commonly a class accessed via reflection that ProGuard's static analysis can't detect as actually being used.
The Problem
A debug build works completely normally, but a release build (or a build submitted to internal testing/production) crashes on launch, often before any UI is visible at all:
FATAL EXCEPTION: main
java.lang.NoClassDefFoundError: com.facebook.hermes.reactexecutor.HermesExecutor
E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to instantiate application
com.example.app.MainApplication: java.lang.ClassNotFoundException
Checking adb logcat is essential here, since without a device connected and logs visible, all you see on the device itself is the app closing immediately with no visible error information at all.
Why It Happens
ProGuard (or its modern replacement, R8) analyzes your code statically to determine what's actually used, removing (shrinking) and renaming (obfuscating) anything it doesn't detect as reachable — this process works well for normal Java/Kotlin method calls, but can't see usage patterns based on reflection, JNI (native code calling into Java), or certain React Native internal mechanisms, since these don't appear as ordinary, staticaly-analyzable code references. Common causes:
- A required class or method used internally by React Native's own bridge, Hermes engine integration, or a native module gets stripped or renamed by ProGuard because it's only referenced via reflection or JNI, which ProGuard's static analysis doesn't recognize as a real usage
- A third-party native module's own required ProGuard keep rules weren't included, since some libraries require consumers to manually add specific keep rules documented in the library's own installation instructions, rather than the rules being applied automatically
- Custom ProGuard rules in the project conflicting with or overriding rules that React Native's own default configuration would have otherwise correctly applied
- An upgrade to a newer React Native or Hermes version introducing new internal classes that existing custom ProGuard rules don't yet account for
The Fix
First, confirm this is genuinely a ProGuard/shrinking issue by temporarily disabling minification for a release build, to see whether the crash disappears — this isolates the cause before you invest time writing specific keep rules:
// android/app/build.gradle
buildTypes {
release {
minifyEnabled false // temporarily, for diagnosis only
}
}
If the crash disappears with minification off, ProGuard/R8 is confirmed as the cause, and the fix is adding the correct keep rules rather than permanently disabling minification (which you generally want enabled in production for both app size and a degree of code obfuscation).
Add or confirm the standard React Native and Hermes keep rules exist in your ProGuard configuration — modern React Native versions typically include sensible defaults automatically, but confirm they're actually present and not being overridden:
# android/app/proguard-rules.pro
-keep class com.facebook.hermes.unicode.** { *; }
-keep class com.facebook.jni.** { *; }
-keep class com.facebook.react.bridge.** { *; }
-keep class com.facebook.react.turbomodule.core.** { *; }
For a specific third-party native module causing the crash, check that library's own documentation for required ProGuard rules — many popular React Native libraries document specific keep rules needed when minification is enabled, precisely because their own native code relies on patterns ProGuard's default analysis can't safely detect:
# Example rule pattern many libraries require - check your specific library's docs
-keep class com.thelibraryname.** { *; }
-dontwarn com.thelibraryname.**
Re-enable minification and rebuild once the appropriate keep rules are added, confirming the crash is genuinely resolved rather than just temporarily masked by having disabled shrinking entirely:
// android/app/build.gradle
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
Still Not Working?
If adding known common keep rules doesn't resolve the crash, get the exact class name being stripped or misresolved directly from the crash log, and add a targeted keep rule specifically for it, rather than guessing broadly:
adb logcat | grep -A 5 "FATAL EXCEPTION"
The exact class name reported in a ClassNotFoundException or NoClassDefFoundError tells you precisely what ProGuard removed or renamed — adding a specific keep rule for that exact class (and its package, if the issue extends beyond a single class) directly resolves the specific crash, even in cases where no publicly documented keep rule already exists for that particular scenario.