How to Shrink a React Native App's Download Size
Reduce React Native app size in 2026: measure what users download, Android App Bundles, R8 shrinking, assets, fonts, dependencies and native SDKs.
Full-Stack, Mobile & AI Engineer
App size feels like a vanity metric until you look at who isn't installing. A large download is a reason to "do it later on Wi-Fi", and later often never comes, especially in markets where mobile data is expensive or devices have little free storage. Size also slows updates, which means more users stay on old versions with old bugs.
This guide covers how to reduce React Native app size in practice: how to measure what users actually download, which build settings matter on Android and iOS, and where the megabytes usually hide (assets, fonts, dependencies and native SDKs).
Key takeaways
- Measure the download size users get, not the size of the file you upload. Play Console and App Store Connect both report it.
- Ship Android App Bundles; Google Play then delivers optimised APKs per device, with only the right CPU architecture, screen density and languages.
- Turn on R8 code and resource shrinking for Android release builds.
- Assets and native SDKs are usually the biggest wins: large images, bundled videos, unused fonts and heavy third-party SDKs.
- Remove dependencies you don't use. Every native library adds compiled code to both platforms.
Step 1: measure the right number
The file you upload is not what users download:
- Android: an App Bundle (AAB) contains code and resources for every device type. Google Play generates device-specific APKs from it. Play Console's app size report shows the actual download and install sizes.
- iOS: App Store "app thinning" delivers variants per device. Exporting an app thinning size report from Xcode, or checking sizes in App Store Connect, shows what each device downloads.
Record the download size for a typical mid-range Android phone and a current iPhone, then measure again after each change.
Step 2: Android build settings
| Setting | What it does | How to enable |
|---|---|---|
| Android App Bundle | Per-device APKs from Google Play | Default for new Play apps and EAS builds |
| R8 code shrinking | Removes unused Java/Kotlin code and obfuscates | minifyEnabled true in release, or android.enableProguardInReleaseBuilds in expo-build-properties |
| Resource shrinking | Removes unused Android resources | shrinkResources true, or android.enableShrinkResourcesInReleaseBuilds in Expo |
| Architecture splits | One CPU architecture per device | Automatic with App Bundles |
After enabling shrinking, test the release build thoroughly. Libraries that use reflection sometimes need keep rules, and a missing rule shows up as a crash only in release builds.
iOS-specific tips
On iOS, the App Store already thins apps per device, so most savings come from what you include rather than build flags. Keep assets in asset catalogs so Xcode can deliver only the right resolution, make sure debug symbols aren't shipped inside the app bundle (upload them to your crash reporter instead), and remove unused app extensions or frameworks left over from old features.
Step 3: assets
Assets are the most common source of avoidable size:
- Images: compress them, use WebP, and remove unused ones. Search the codebase for every asset in your
assetsfolder; unused files are surprisingly common. - Large media: don't bundle videos or big illustrations needed on one screen. Download them on demand and cache them.
- Animations: Lottie files can be large; simplify them or load them remotely.
- Fonts: include only the weights you use, and subset fonts to the characters you need, especially for large scripts.
Step 4: dependencies and native SDKs
Each library with native code adds compiled code to both apps, and some SDKs (analytics suites, ad SDKs, video players, maps) are large on their own.
- List your native dependencies and ask of each: do we still use it, and is there a lighter alternative?
- Avoid two libraries doing the same job, such as two image pickers or two analytics SDKs.
- Check transitive dependencies: one convenient library can pull in a large native SDK you never call.
- Prefer Expo modules or small focused libraries over all-in-one packages.
Step 5: JavaScript bundle
The JavaScript bundle (compiled to Hermes bytecode) is usually not the biggest part of the download, but it still matters for size and startup:
- Remove unused packages from
package.json. - Replace heavy utility libraries with lighter ones or native APIs (
Intlfor dates and numbers). - Avoid importing whole libraries when you need one function.
From the field: On the apps where I cut load time by about 60% (3.8 seconds to 1.5), image optimisation was one of the three main levers alongside Hermes and cache-first fetching. Images are usually where both download size and startup cost hide, so they're the first place I'd look.
A practical size budget
Set a budget and check it in CI or at least before each release: for example, "download size on a mid-range Android phone stays under X MB". When a pull request adds a large SDK or asset, the budget turns "it's only a few megabytes" into a conscious decision instead of slow drift.
Common causes of sudden growth
| What happened | Typical cause |
|---|---|
| Download jumped by many megabytes | A new native SDK (ads, video, maps, analytics) |
| Android much bigger than iOS | R8 or resource shrinking disabled, or universal APK uploaded instead of an AAB |
| Size grew steadily over months | Unused assets and dependencies never removed |
| Fonts folder is large | Every weight and full character sets bundled |
FAQ
How do I reduce the size of my React Native app?
Measure the real download size in Play Console and App Store Connect, ship Android App Bundles with R8 code and resource shrinking, compress and prune assets, subset fonts, and remove unused or heavy native dependencies. Assets and native SDKs usually give the biggest savings.
Why is my React Native APK so large?
A universal APK contains code and resources for every CPU architecture and screen density. Uploading an Android App Bundle lets Google Play deliver a smaller, device-specific APK. Large bundled assets and native SDKs also add significantly.
Does Hermes make the app bigger?
Hermes ships an engine and precompiled bytecode, but it replaces runtime compilation work and is the default engine. Its effect on size is usually small compared with assets and native SDKs, and its startup benefits outweigh it.
Should I enable ProGuard or R8 in React Native?
Yes, for release builds. R8 removes unused code and resources and obfuscates the rest, reducing download size. Test release builds carefully afterwards, because some libraries need keep rules to work with shrinking.
Next steps
If your app's download size keeps growing, I can measure where the megabytes come from and reduce them without breaking features. Get in touch, or see how I work as a React Native developer.
Sources
- About Android App Bundles, Android Developers
- Shrink, obfuscate, and optimize your app, Android Developers
- BuildProperties (expo-build-properties), Expo
- Reducing your app's size, Apple
Related
How We Cut React Native Startup Time from 3.8s to 1.5s
The levers that cut React Native startup time by about 60%: measuring cold start properly, Hermes, image optimisation and cache-first fetching.
React Native Performance in 2026: The Checklist That Matters
A practical React Native performance optimization checklist for 2026: measuring, startup, re-renders, lists, images, animations, memory and monitoring.
Hermes in 2026: What It Does and How to Profile with It
What Hermes does for React Native in 2026, what changed with Hermes V1, Hermes vs JavaScriptCore, and how to profile CPU and memory with DevTools.
