How to Reduce Your Expo App's Size Before You Submit It

DavidDavid August 31, 2026 9 min read
A smartphone resting on one side of a small vintage brass balance scale, weighed against a single smooth stone, on a dark wood desk in soft directional light
Original image, App Store Launch Club

The short answer

Reducing your Expo app's size comes down to three things, in order: measure what users actually download (not the build file on your machine), find where the bloat lives (almost always assets, occasionally the JS bundle), and cut it before you submit rather than after you have live users on an old version. Apple will not reject you for a big app short of the 4GB uncompressed ceiling, which no indie app gets near. The reason to care is the 200MB default on cellular downloads, which is a real point of friction between someone tapping Get and someone actually installing your app.

Expo's own guidance is blunt about the first mistake: people look at the size of the .ipa or .aab file they built and assume that is what users download. It usually is not. App Store Connect and Google Play both generate device-specific, thinned packages from that build artifact, so the real download size is smaller and only visible in the store's own tooling, not in your build output.

Why size is a growth problem, not usually a rejection

Two separate Apple limits get confused constantly, and only one of them can block your submission. The App Store's uncompressed app size limit is 4GB, a ceiling raised from 2GB back in 2015 and never lowered since. A typical Expo app, even one loaded with images, video, and fonts, is nowhere near it. If App Review rejects you, it is not because of file size.

The number that actually matters day to day is 200MB, and it is not a rejection threshold at all, it is a cellular download setting. iOS's current default is to ask before downloading anything over 200MB unless the user is on Wi-Fi or has switched their App Store cellular setting to always allow larger downloads. Someone tapping your app from a search result on their phone, on data, mid-scroll, hits that prompt and has to make a decision you would rather they didn't have to make.

How to see what users actually download

Stop reading your local build output. Check the number the stores actually show a device.

  • iOS: In App Store Connect, open your build under TestFlight and look at the estimated download and install size per device. This is the thinned, device-specific number, and it is the one worth tracking release over release.
  • Android: Use the Android APK Analyzer, apktool, or the size figures inside the Google Play Developer Console. Android App Bundles get split further than iOS thinning does, so the store-listed download size is usually meaningfully smaller than your local .aab.
  • JavaScript bundle: Run Expo Atlas against your project to see what is actually inside your JS bundle, dependency by dependency, rather than guessing from package.json.

If you have not gotten a build into TestFlight yet, [the TestFlight beta testing guide for Expo apps](/blog/testflight-beta-testing-guide-for-expo-apps) covers getting a build there in the first place, which is also the fastest way to see your real per-device number before you submit for review.

Where the bloat actually comes from

Expo's own documentation identifies static assets as the single most common source of app size bloat: fonts, icons, images, video, and audio, including ones pulled in silently by a library you added for one small feature. This is almost always the first place to look, not the JS bundle.

  • Full-resolution images dropped straight from a design tool or a phone camera roll, never resized for the largest size they are actually displayed at.
  • Every weight of a font family imported when the app only ever uses two of them.
  • Video or audio files kept for a feature that shipped differently, or a splash animation nobody trimmed down.
  • Unused image format decoders. Expo's Android template enables GIF and WebP decoding by default, which most apps never use but still ship.
  • Starter-template assets left in the project after the tutorial images and placeholder icons were replaced in the UI but never deleted from the assets folder.
  • A dependency added for one feature that quietly bundles its own large media or font files.

None of this is exotic. It is the accumulation of small, reasonable-at-the-time decisions across a project's first few weeks, which is exactly why it is worth a deliberate pass before you submit rather than something you catch by accident.

The fixes, in the order that actually moves the number

  1. Resize and compress every image to the largest size it is actually rendered at on the largest supported device, not the resolution it came out of your camera or design file at.
  2. Delete font weights you imported but never reference in a style. Check every family, not just the ones you remember adding.
  3. Disable unused image format decoders on Android through expo-build-properties if your app never displays GIFs or WebP images.
  4. Run Expo Atlas and look for a dependency that is unexpectedly large relative to what it does for you. A single unused import from a big library can pull in far more than the feature justifies.
  5. Search your assets folder for anything you do not remember adding on purpose. Template leftovers and abandoned feature assets hide here more often than anywhere else.
  6. Confirm you are not shipping dev-only or debug assets in a production build profile in eas.json.

Do this pass before your first submission if you can, because it costs almost nothing at that point. Doing it after you have real users on an older, heavier version costs you an update cycle and a size regression nobody asked for. If you are also mid rebuild for a new SDK version, [how to upgrade your Expo SDK version](/blog/how-to-upgrade-your-expo-sdk-version) is the moment default packaging behavior can change under you, so it is worth re-checking size right after any SDK bump, not just before your first submission.

Point the Claude Code desktop app at your assets folder

This is a genuinely good use of Claude Code, because the tedious part of a size audit is reading through every file in a growing assets folder and every entry in package.json, not making the judgment call about what to cut. Open the Claude Code desktop app in your project root and work through it directly, rather than piping file listings through a terminal by hand.

  • Ask it to list every file under assets/ above a size threshold you set, sorted largest first, so you see the worst offenders immediately.
  • Ask it to check whether app.json or app.config.ts already configures expo-build-properties to disable unused image decoders, and to add that config if it is missing.
  • Ask it to cross-reference your imported font families against every style that actually references a font weight, and flag any weight that is bundled but never used anywhere in the codebase.
  • Ask it to scan for obvious leftover template assets, placeholder icons, or sample media that shipped with the starter project and were never removed.

You still make the call on what to delete. The value is having something read the whole tree at once and hand you a shortlist, instead of you clicking through folders one by one. If you have not set project-level conventions for Claude Code yet, [CLAUDE.md for Expo apps](/blog/claude-md-for-expo-apps) is worth setting up first so it already knows your asset and build conventions before you ask it to audit them.

When size actually becomes a hard limit

Keep the two numbers separate in your head, because they mean different things and call for different responses.

LimitWhat it actually isWhat happens if you hit it
4GBApple's ceiling on the uncompressed .app bundle for App Store submission.Your build fails to submit. No indie Expo app gets close to this in practice.
200MBiOS's default threshold for asking a user to confirm before downloading over cellular.Nothing is blocked. The user sees a prompt and can choose Wi-Fi, allow it anyway, or leave.

In practice, the 4GB ceiling is a non-issue for an Expo app built with typical assets. The 200MB threshold is the one worth actively managing, because it sits directly in the path between someone finding your app and someone finishing the install.

A pre-submission size checklist

  1. Check the real per-device download size in App Store Connect and the Google Play Developer Console, not your local build file.
  2. Run Expo Atlas and confirm nothing unexpected is pulling in an oversized dependency.
  3. Resize and compress every image to the size it is actually displayed at.
  4. Delete unused font weights and any leftover starter-template assets.
  5. Disable unused image format decoders through expo-build-properties if you do not use GIF or WebP.
  6. Re-check size after any Expo SDK upgrade, since default packaging behavior can shift between versions.
  7. Treat 200MB as the practical number to stay under, and 4GB as the ceiling you almost certainly will never approach.

This pairs well with the rest of your pre-submission pass. If you have not walked the full checklist yet, [the App Store submission checklist](/guides/app-store-submission-checklist) covers everything else Apple expects before your first review.

Free app-building tips, straight to your inbox

Short, practical drops on app ideas, validating fast, store listings, and passing app review. No spam, unsubscribe anytime.

Frequently asked questions

Does Apple reject apps for being too large?

Almost never on size alone. Apple's limit is a 4GB uncompressed .app bundle for App Store submission, and no typical indie Expo app comes close to it. Rejections tied to size are rare and usually involve something unusual, not a normal app with a heavier-than-average asset folder.

What is the actual cellular download limit for App Store apps?

iOS's current default asks a user to confirm before downloading anything over 200MB on cellular, unless they are on Wi-Fi or have changed their App Store cellular setting to always allow larger downloads. It is a confirmation prompt, not a hard block, but it is friction between a tap and an install that a smaller app avoids.

Why is my build file so much bigger than what shows in the App Store?

The .ipa or .aab file you build locally includes resources for every supported device. App Store Connect and Google Play both generate thinned, device-specific packages from that file, so the number a real user downloads is smaller. Check the estimated size inside App Store Connect or the Play Console, not your local build output.

What usually takes up the most space in an Expo app?

Static assets, according to Expo's own documentation: fonts, icons, images, video, and audio, including ones pulled in by a library rather than added directly. JS bundle bloat happens too, but assets are the more common and usually the larger source in a typical first app.

How big is a minimal Expo app supposed to be?

Expo's own minimal blank template comes in just under 4MB on the App Store. That is a useful baseline: if your first app is several times that size, the difference is almost certainly identifiable assets or dependencies, not something inherent to Expo itself.

Should I disable image format decoders I don't use?

Yes, if you never display GIFs or WebP images. Expo's Android template enables both decoders by default, and expo-build-properties lets you turn off the ones your app never actually uses, which is a small, low-risk size reduction most projects never bother making.

Last reviewed by David on August 31, 2026

David

Written by

David

Founder and app builder

Keep reading

App StoreLaunch

App Store Phased Release: How the 7-Day Rollout Works, How to Pause It, and When to Skip It

App Store phased release rolls a version update out to a random sample of users with automatic updates on over 7 days: 1 percent on day one, then 2, 5, 10, 20, 50 and 100. You can pause it for up to 30 days in total, or release to everyone with one button. Here is exactly what Apple says it does, what it does not do, and how I decide when an Expo app update should use it.

David 8 min
Read article
App StoreLaunch

App Store Pre-Order: How to Set It Up for Your First Expo App (and When It Is Worth It)

An App Store pre-order publishes your product page before your release date so people can order the app, and on launch day it downloads to their device automatically. Apple only publishes the pre-order after the build has passed App Review, the release date has to sit two to 180 days out for a brand-new app, and you have to release the version manually. Here is how to set it up in App Store Connect for an Expo app, what Apple charges and when, and the three questions I use to decide whether a pre-order is worth the wait.

David 9 min
Read article

Ready to build it yourself?

Join App Store Launch Club, the #1 community for building and launching apps, for $9/month.

← Back to the blog