Muhammad Uzair
Performance

How to Reduce Flutter App Size: 12 Proven Techniques

Published: 2026-10-07 · 10 min read

Is your Flutter APK pushing 50MB? 12 proven techniques to shrink app size: app bundles, ABI splits, R8 shrinking, deferred components, and asset optimization.

How to Reduce Flutter App Size: 12 Proven Techniques That Actually Work

You've built a beautiful Flutter app. It runs flawlessly. Then you check the APK size: 47MB. For a todo app. Meanwhile, a comparable native app ships at 12MB. What gives — and more importantly, how do you fix it?

Flutter apps carry inherent weight: the Dart VM/engine (~4-7MB per ABI), ICU internationalization data, and the framework itself. A minimal release APK starts around 15-20MB before you write a single line of code. But most bloated Flutter apps I audit aren't victims of the engine — they're victims of avoidable mistakes: unoptimized assets, unused dependencies, and debug-era build configs shipped to production.

Here are 12 techniques I use to slim down production Flutter apps, ordered roughly by impact.


1. Measure First: Know Where the Megabytes Live

Never optimize blindly. Flutter ships a built-in size analyzer:

flutter build apk --analyze-size

Or for a visual breakdown:

flutter build apk --analyze-size --target-platform=android-arm64

This generates a size report showing exactly how much each Dart package, asset, and native library contributes. In my experience, the top offenders are almost always: uncompressed images, a forgotten ML model file, or a dependency that pulled in half of the ecosystem.


2. Ship an App Bundle, Not an APK

If you're distributing via Google Play, always upload an Android App Bundle:

flutter build appbundle --release

Google Play then generates optimized APKs per device — each user downloads only the resources, native libraries, and ABIs their specific device needs. This alone typically cuts download size by 30-50% compared to a fat APK. There is no reason to upload a universal APK to the Play Store in 2026.


3. Split by ABI

If you must distribute APKs directly (enterprise MDM, alternative stores), split per CPU architecture:

flutter build apk --split-per-abi --release

This produces separate APKs for armeabi-v7a, arm64-v8a, and x86_64 instead of one fat binary containing native libraries for all three. Each APK drops roughly 4-8MB of native code the device will never execute.

Going further: if your analytics show 99% of users on 64-bit devices (true for virtually every app in 2026), target only what you need:

flutter build apk --release --target-platform=android-arm64

4. Enable R8 Shrinking and Resource Shrinking

This is the single most overlooked setting. Open android/app/build.gradle.kts (or build.gradle) and make sure your release block looks like this:

buildTypes {
    release {
        signingConfig = signingConfigs.getByName("release")
        isMinifyEnabled = true
        isShrinkResources = true
        proguardFiles(
            getDefaultProguardFile("proguard-android-optimize.txt"),
            "proguard-rules.pro"
        )
    }
}

isMinifyEnabled runs R8 to strip unused Java/Kotlin code from your dependencies. isShrinkResources removes unused resources (layouts, drawables, strings) that R8 determined are unreachable. Together they commonly save 2-5MB — and I've seen far more in apps with heavy native SDKs.

Warning: shrinking can break reflection-based libraries. Test thoroughly after enabling, and add -keep rules for anything that breaks.


5. Tree-Shake Your Icons

Flutter bundles the entire Material Icons font (~1.5MB+) unless you tell it not to. Tree-shaking strips unused glyphs:

flutter build apk --tree-shake-icons

This is enabled by default in release builds for most configurations, but if you've ever disabled it or use a custom build pipeline, verify it's on. If you only use Cupertino icons, consider dropping the Material font entirely.


6. Audit Your Dependencies Ruthlessly

Run this and prepare to be horrified:

flutter pub deps

Every package you add drags in its transitive dependencies — Dart code, native libraries, and sometimes bundled assets. Common sins I find in audits:

  • A full Firebase suite when the app only uses Auth
  • Image picker packages that bundle their own compression native libs
  • Date formatting packages pulling in massive locale datasets

Remove what you don't use. For what remains, check if lighter alternatives exist. One client's app dropped 9MB just by replacing three heavy packages with focused alternatives.


7. Compress and Right-Size Your Images

Images are the #1 cause of unexpected bloat. Rules I enforce on every project:

  • Convert PNG/JPEG to WebP. WebP delivers 25-35% smaller files at identical quality. Flutter supports WebP on all platforms.
  • Ship correctly sized assets. Don't bundle a 4000px photo displayed at 200px. Resize to 2x/3x variants only.
  • Strip metadata. Camera EXIF data adds kilobytes per image for zero benefit.
  • Prefer vector. Simple icons and illustrations should be SVG (via flutter_svg), not raster images.

A quick audit command to find the worst offenders:

find assets -type f -size +500k | sort

8. Subset Your Fonts

Custom fonts are shockingly heavy — a full variable font with CJK glyphs can exceed 10MB. If your app only needs Latin characters:

  • Use font subsetting tools to strip unused glyph ranges
  • Load only the weights you actually use (don't bundle Light through Black if you only use Regular and Bold)
  • Consider system fonts for body text and reserve custom fonts for headings

9. Use Deferred Components (Android)

For large apps, Flutter supports deferred components — features downloaded on demand after install:

import 'expensive_feature.dart' deferred as expensive;

Future<void> loadFeature() async {
  await expensive.loadLibrary();
  expensive.ExpensiveWidget();
}

This moves rarely-used features (onboarding tours, admin panels, AR modules) out of the base APK. It's Android-only and adds complexity, so reserve it for genuinely large optional features — but when it fits, the savings are dramatic.


10. Clean Up Your Assets Folder

Over a project's lifetime, assets/ accumulates dead weight: old onboarding illustrations, unused Lottie files, placeholder videos. Lottie JSON files especially — a single complex animation can be 500KB+.

Do a quarterly asset audit. If it's not referenced in code, delete it. If it is referenced but rarely seen, consider loading it from CDN instead of bundling.


11. iOS-Specific: Strip Symbols and Optimize

For iOS builds:

  • Bitcode is long gone, but make sure you're building with the release configuration: flutter build ipa --release
  • Enable STRIP_INSTALLED_PRODUCT = YES in Xcode build settings to strip debug symbols
  • Compress bundled videos/images the same as Android — iOS asset catalogs don't do it for you
  • If you embed Flutter as a module (add-to-app), audit the engine version — each Flutter upgrade changes the engine footprint

12. Automate Size Tracking in CI

The best technique is the one that prevents regressions. Add a size check to your CI pipeline:

## .github/workflows/size-check.yml
- run: flutter build appbundle --release
- run: |
    SIZE=$(stat -c%s build/app/outputs/bundle/release/app-release.aab)
    echo "Bundle size: $((SIZE / 1024 / 1024))MB"
    if [ $SIZE -gt 52428800 ]; then
      echo "Bundle exceeds 50MB budget!" && exit 1
    fi

A size budget in CI turns bloat from a surprise into a failing test. Pick a number, enforce it, and watch your app stay lean.


Realistic Expectations

Here's what these techniques typically achieve on a real-world app:

Starting point Achievable Key levers
60MB+ fat APK 20-30MB download App bundle + ABI split + R8
30-40MB bundle 15-25MB Asset optimization + dep audit
15-25MB bundle 10-18MB Deferred components + font subsetting

You'll never beat a native app on raw size — the Flutter engine has a fixed cost. But there's no reason a well-built Flutter app should feel bloated. Most apps I audit can shed 40-60% of their download size with the techniques above, and users absolutely notice: smaller downloads mean higher install conversion, especially in emerging markets where your next million users live.

Start with --analyze-size, fix the top three offenders, and put a budget in CI. Your users' storage — and your Play Store conversion rate — will thank you.

Frequently Asked Questions

How do I find out what is making my Flutter app so big?

Run flutter build apk --analyze-size (or --target-platform=android-arm64 for a visual breakdown). It generates a size report showing exactly how much each Dart package, asset, and native library contributes - the top offenders are almost always uncompressed images, a forgotten ML model file, or a dependency that pulled in half the ecosystem.

Why is my Flutter APK 47MB when a native app is 12MB?

The engine is not the main problem - a minimal release APK starts around 15-20MB. Bloat comes from avoidable mistakes: unoptimized assets, unused dependencies, and debug-era build configs shipped to production. Images are the number-one cause of unexpected bloat.

How do I reduce image bloat in a Flutter app?

Convert PNG/JPEG to WebP for 25-35% smaller files at identical quality, ship correctly sized assets (2x/3x variants only, not 4000px photos displayed at 200px), strip EXIF metadata, and prefer SVG vectors for icons and illustrations.

Related Articles

← Back to all articles