The Flutter Kit logoThe Flutter Kit
Guide

Flutter App Size Optimization 2026: Cut APK and IPA by 50% (Checklist)

The complete 2026 checklist that actually shrinks Flutter app size. Measurement, tree shaking, ABI splits, font subsetting, iOS stripping, and a real 24 MB to 11 MB case study.

Ahmed GaganAhmed Gagan
14 min read

Flutter apps are fat by default. A fresh flutter create spits out a release APK north of 22 MB and an IPA north of 28 MB before you've written a line of code. Ship without thinking about size and you're handing users a 50 MB download that drops installs, especially in emerging markets. This is the 15-item checklist I run on every Flutter release. Followed end to end it cuts typical Flutter app size by 45 to 60 percent.

Short version: measure first, tree-shake everything, split ABIs, subset fonts, compress assets, strip iOS debug symbols, and audit dependencies. Each step is small; the compound effect is massive. Real example at the bottom: my habit-tracker template went from a 24 MB APK to an 11 MB APK following this list.

Why Flutter apps are bloated by default

Flutter ships the Dart VM, Skia or Impeller graphics, ICU internationalization data, Material and Cupertino widget libraries, and your app code, all inside a single binary. On Android you also get four ABI variants (arm64-v8a, armeabi-v7a, x86_64, x86) packed into one APK unless you tell the build system otherwise. On iOS you inherit Swift runtime plus your Dart snapshot plus bitcode stubs. The total adds up quickly.

The optimizations below are roughly in order of impact. Work the top of the list first.

1. Measure before you optimize

Every decision after this step is easier when you have numbers. Flutter ships a build-size analyzer that writes a JSON report and opens a visual tree explorer.

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

The command exits with the path to a .json report. Load it atdevtools.flutter.dev/appsize for a treemap. You will discover specific packages that dominate: font_awesome_flutter burns 2 MB, a single unused SVG pack burns 800 KB, a locale-heavy intl data file hits 1.4 MB. Baseline first, then optimize.

2. Enable tree shaking and release mode (obvious but often skipped)

Flutter's release builds already tree-shake Dart code and icons, but only when you actually build release. In CI I still see teams shipping profile or debug builds to Play Console because someone tested with flutter build apk without flags.

  • Always --release for Play Store / App Store.
  • Set --tree-shake-icons (default on release, but double-check your CI).
  • Enable --split-debug-info=./symbols to strip debug info from the binary while keeping symbol files for crash reports.
  • Add --obfuscate if your Dart code contains proprietary logic.

3. Ship Android App Bundles, not APKs

Play Console has required AAB for new apps since 2021 but some teams still upload a universal APK for testing channels. AAB is 25 to 35 percent smaller at install time because Play slices it into device-specific APKs.

flutter build appbundle --release \
  --split-debug-info=./symbols \
  --tree-shake-icons

4. ABI splits save 40 to 60 percent on Android

If you still need APKs (sideload distribution, alternative stores), split them by ABI. A single architecture APK is typically 40 percent the size of a universal one.

// android/app/build.gradle
android {
  splits {
    abi {
      enable true
      reset()
      include 'armeabi-v7a', 'arm64-v8a', 'x86_64'
      universalApk false
    }
  }
}

Do not ship x86 unless you target Chromebook or specific Android emulators. Almost all real devices are arm64-v8a.

5. Subset fonts (this is where most Flutter apps bleed)

The default google_fonts package loads entire font families at runtime, which is great in debug but costs MBs in production. Two options:

  • Pre-bundle only the weights you use. Download the font files, include them inpubspec.yaml, and reference them by name. Typical savings: 500 KB to 2 MB.
  • Use fonttools to subset the glyph set. If your app only renders Latin characters, strip CJK, Cyrillic, and symbol ranges. Can cut a font from 800 KB to 80 KB per weight.

Icon fonts are worse. font_awesome_flutter is 2 MB on disk. Flutter's built-in--tree-shake-icons helps, but only for Icons.* usage. If you use FontAwesome you are still shipping the whole font unless you subset it manually.

6. Compress assets: WebP, AVIF, and SVG

Asset typeDefault in FlutterReplace withTypical saving
PNG images (non-photo)PNGWebP lossless or SVG60 to 80 percent
PNG photosPNGWebP lossy (quality 85)70 to 85 percent
JPG photosJPGWebP or AVIF30 to 50 percent
IconsPNG at 3xSVG via flutter_svg90 percent plus crispness
AnimationsGIF or videoRive or Lottie50 to 90 percent

WebP has been supported in Flutter since 3.7. Run every PNG and JPG through cwebpin your build pipeline. One of my apps saved 6 MB by converting the onboarding illustration pack from PNG to WebP.

7. R8 and ProGuard on Android

R8 replaced ProGuard as the default Android shrinker in AGP 3.4+. Flutter release builds already enable it, but you control the rules via proguard-rules.pro. Two quick wins:

  • Add minifyEnabled true and shrinkResources true to your release build type if they are not already set.
  • Avoid -keep class ** wildcard rules that disable minification for whole packages. Only keep the specific classes your reflection or platform channels need.

8. iOS: strip symbols and bitcode

iOS IPAs bundle LLVM bitcode by default and keep debug symbols until you tell Xcode to strip. Apple stopped requiring bitcode in Xcode 14+. Turning it off saves 15 to 25 percent on IPA size.

  • Xcode → Build Settings → Enable Bitcode → No.
  • Xcode → Build Settings → Strip Debug Symbols During Copy → Yes.
  • Xcode → Build Settings → Deployment Postprocessing → Yes.
  • Xcode → Build Settings → Strip Style → All Symbols.

Set these in the Release configuration only so debug builds keep their symbols.

9. Kill unused locales

Flutter bundles ICU locale data for every supported language. If you only ship to English and Spanish markets, you can safely strip the rest. Edit your MaterialApp to declare only the locales you need, then tree-shaking cuts the data files automatically on iOS and Android.

10. Audit your dependency tree

Every package you add has a size cost. Run flutter pub deps and cross-reference with the build-size report. Common bloat culprits:

  • firebase_crashlytics adds 1.8 MB. Worth it for production.
  • google_maps_flutter adds 2.5 MB. Only include on screens that need it.
  • video_player with chewie adds 3 MB. Consider a web-view for rare video cases.
  • share_plus, url_launcher, package_info_plus: thin, keep.
  • Analytics SDKs with session replay: 1 to 3 MB depending on provider.

11. Dynamic feature modules (Android only)

Play App Bundles support dynamic feature modules that download on demand. If you have a video player or an AR experience that 10 percent of users use, make it a dynamic feature. This pattern is underused in Flutter because it requires a Kotlin wrapper, but the savings are real for feature-rich apps.

12. Remove unused debug tools

Packages you forgot to remove from dependencies:

  • logger output in release: strip via wrapping in kReleaseMode.
  • flutter_inspector: dev-only.
  • flutter_test: should be in dev_dependencies.
  • Leftover example assets from flutter_animate, rive tutorials.

13. Use flutter_launcher_icons smartly

flutter_launcher_icons generates every icon size by default. If you only target iOS or only target Android, skip the other set in the config. Savings: 200 to 400 KB.

14. Profile mode before release (catch bloat early)

Run flutter build apk --profile --analyze-size as part of your PR CI pipeline. Profile builds are only 5 to 10 percent larger than release and catch size regressions before they merge. Configure a threshold: fail CI if APK grows more than 500 KB in a single PR.

15. Before and after: a real case study

Here is the size journey for a habit tracker app built on Flutter Kit, starting from the default and applying every optimization above.

StepAPK sizeChange
Fresh Flutter Kit clone, universal APK, debug fonts24.1 MBbaseline
Switch to App Bundle17.8 MB-26 percent
ABI split (arm64 only)13.4 MB-25 percent
Subset fonts + kill FontAwesome12.1 MB-10 percent
WebP assets, SVG icons11.4 MB-6 percent
R8 tuning, strip symbols11.1 MB-3 percent
Final11.1 MB-54 percent total

The first three steps (bundle, ABI, fonts) do 80 percent of the work. The rest is polish. If you have one afternoon, do those three.

Common mistakes that re-bloat your app

  • Adding flutter_local_notifications and its 1.2 MB ICU dep without realizing it bundles a second locale database.
  • Using cached_network_image with default cache settings (300 MB on-device cache, not a binary size issue but a real storage issue).
  • Importing the whole lodash-equivalent Dart utility package for one function.
  • Letting generated_plugin_registrant.dart stay after removing a plugin.
  • Shipping multiple PNG densities when you already have a WebP fallback chain.
  • Including animation JSON files that are copies of a Figma export, not optimized Lottie output.

What The Flutter Kit ships

The Flutter Kit ships with the optimizations in this guide already applied. AAB build config, ABI split with arm64 default, WebP asset pipeline, subsetted font files, production-tuned R8 rules, and the iOS Build Settings configured for size. A typical Flutter Kit release APK lands at 12 to 14 MB before you add your own assets.

$69 one-time, unlimited commercial projects. See every integration on the features page or jump to checkout.

Final checklist (print this before your next release)

  • Measured baseline with --analyze-size
  • Release build with tree shaking and icon shaking enabled
  • Android App Bundle, not universal APK
  • ABI split configured for arm64 + armeabi-v7a only
  • Fonts subsetted or pre-bundled (no google_fonts runtime on release)
  • Images converted to WebP or SVG
  • R8 minify and shrink resources enabled
  • iOS bitcode disabled, symbols stripped
  • Unused locales removed
  • Dependency tree audited against size report
  • CI size-regression gate in place
Share this article

Ready to ship your Flutter app faster?

The Flutter Kit gives you a production-ready Flutter codebase with onboarding, paywalls, auth, AI integrations, and more. Stop building boilerplate. Start building your product.

Get The Flutter Kit