There is nothing more frustrating than finishing a feature and realizing your production build has ballooned to 60MB for a simple utility app. When I first started building for production, I ignored the binary size until my conversion rates dropped because users in emerging markets refused to download a massive app. If you’re wondering how to reduce React Native app size, you aren’t alone—it’s one of the most common hurdles in moving from a prototype to a polished product.
Reducing your app size isn’t just about deleting images; it’s about optimizing the JavaScript engine, stripping unused native code, and managing how assets are bundled. In this tutorial, I’ll walk you through the exact steps I use to trim the fat from my React Native binaries.
Prerequisites
- A React Native project (0.70+ recommended)
- Android Studio and Xcode installed and configured
- Basic familiarity with
gradleandpodfiles - A release build configured (you cannot accurately measure size using debug builds)
Step 1: Enable the Hermes Engine
If you are still using the old JSC engine, you are leaving significant size savings on the table. Hermes is an open-source JS engine optimized for React Native. It pre-compiles JavaScript into bytecode, which reduces the app size and improves start-up time.
For Android, open android/app/build.gradle and ensure enableHermes is set to true:
{
"android": {
"enableHermes": true
}
}
In modern React Native versions, this is the default, but it’s worth verifying. Switching to Hermes often results in a noticeable drop in the final APK size because the JS bundle is more efficiently packed. This is a core part of react native performance optimization tips that I always implement first.
Step 2: Enable ProGuard for Android
ProGuard is a free tool that shrinks, optimizes, and obfuscates your Java bytecode. It removes unused code from your dependencies, which is where most of the bloat hides.
Go to android/app/build.gradle and set enableProguardInReleaseBuilds to true:
def enableProguardInReleaseBuilds = true
When I first enabled ProGuard, my app crashed because it stripped out classes used by reflection. If you encounter this, you’ll need to add keep rules to proguard-rules.pro. For example, if a library like Retrofit is crashing, add:
-keep class retrofit2.** { *; }
Step 3: Optimize Images and Assets
Images are usually the largest contributors to app size. Using raw PNGs or high-res JPEGs is a mistake. I recommend moving toward WebP or using a CDN for non-critical assets.
- Convert to WebP: Use tools like Squoosh or CLI converters to turn PNGs into WebP. It often reduces size by 30-50% without visible quality loss.
- Use SVGs: For icons, stop using PNGs. Use
react-native-svg. - Remove unused assets: I often use a script to find files in
src/assetsthat aren’t imported anywhere in the codebase.
As shown in the image below, the difference between a raw PNG and an optimized WebP can be staggering when scaled across hundreds of assets.
Step 4: Configure Android App Bundles (.aab)
Stop uploading .apk files to the Google Play Store. Use the Android App Bundle (.aab) format. Google Play uses the bundle to generate optimized APKs for each user’s specific device configuration (screen density, CPU architecture).
Run the following command to generate a bundle:
cd android && ./gradlew bundleRelease
This ensures a user with a low-end device doesn’t download high-density images meant for a Pixel 8 Pro, effectively reducing the install size for the end-user.
Step 5: Analyze the Bundle
You can’t fix what you can’t see. I use react-native-bundle-visualizer to see exactly which npm packages are taking up space. This often reveals that a massive library like lodash is being imported entirely instead of just the specific functions needed.
npx react-native-bundle-visualizer
If you find that your third-party dependencies are too heavy, you might want to evaluate your project structure. If you are using Expo, consider whether you are in a managed flow or need the expo vs bare workflow 2026 trade-off to strip out unused Expo modules.
Pro Tips for Extreme Reduction
- Tree Shaking: Ensure you are using ES modules. Instead of
import _ from 'lodash', useimport { debounce } from 'lodash'. - Dynamic Imports: For very large components that aren’t needed at startup, explore lazy loading.
- Remote Assets: Move large onboarding videos or high-res tutorials to an S3 bucket and download them on demand.
Troubleshooting
Issue: App crashes only in release mode after enabling ProGuard.
Solution: This is almost always a missing ProGuard rule. Check your adb logcat for ClassNotFoundException and add the missing class to your proguard-rules.pro file.
Issue: APK size didn’t change after adding WebP.
Solution: Ensure you’ve cleaned your build cache. Run cd android && ./gradlew clean before generating a new release build.
What’s Next?
Once you’ve mastered how to reduce React Native app size, the next step is optimizing runtime performance. A small app that lags is still a bad user experience. I recommend diving into my guide on react native performance optimization tips to ensure your app is as fast as it is lean.