InkdownInkdown
Start writing

Study

69 files·11 subfolders

Shared Workspace

Study
core
Revision w/ Whiteboard

Bundling

Shared from "Study" on Inkdown

React Native / Expo — App Size & Bundle Optimization


The #1 Misconception

The 80-200MB APK/IPA you build locally is not what users download.

ArtifactSize
Universal APK (release build)40-80MB
AAB uploaded to Play Store25-35MB
What user actually downloads (Android)8-15MB
What user actually downloads (iOS)3-8MB
CN Basics - 1
CN Basics - 2
DNS
Event loop
programming-language-concepts.md
zero-language-explanation.md
DB
Quick
databases-deep-dive.md
01-introduction.md
02-relational-databases.md
03-database-design.md
04-indexing.md
05-transactions-acid.md
06-nosql-databases.md
07-query-optimization.md
08-replication-ha.md
09-sharding-partitioning.md
10-caching-strategies.md
11-cap-theorem.md
12-connection-pooling.md
13-backup-recovery.md
14-monitoring.md
15-database-selection.md
README.md
JS
core topics
Event loop
Merlin Backend
01-Orchestration.md
02-DeepResearch.md
03-Search.md
04-Scraping.md
05-Streaming.md
06-MultiProviderLLM.md
07-MemoryAndContext.md
08-ErrorHandling.md
09-RateLimiting.md
10-TaskQueue.md
11-SecurityAndAuth.md
Orchestration-2nd-draft
Mobile
Build Alternative
Bundling
metro-bundler-deep-dive.md
OpenAI Agents Python
00_OVERVIEW.md
01_AGENT_SYSTEM.md
02_RUNNER_SYSTEM.md
03_TOOL_SYSTEM.md
04_ITEMS_SYSTEM.md
05_GUARDRAILS.md
06_HANDOFFS.md
07_MEMORY_SESSIONS.md
08_MODEL_PROVIDERS.md
09_SANDBOX_SYSTEM.md
10_TRACING.md
11_RUN_STATE.md
12_CONTEXT.md
13_LIFECYCLE_HOOKS.md
14_CONFIGURATION.md
15_ERROR_HANDLING.md
16_STREAMING.md
17_EXTENSIONS.md
18_MCP_INTEGRATION.md
19_BEST_PRACTICES.md
20_ARCHITECTURE_PATTERNS.md
opencode-study
context-handling
core
Python
Alembic
Basics
sqlalchemy - fastapi
SQLAlchemy overview
tweets
system_design_for_agentic_apps.md
Agent Loop

A minimal blank Expo app is under 4MB on the App Store. The giant local artifact is a universal dev build — not the shipped product.


Why the Local Artifact is So Large

1. Four CPU architectures bundled into one file Android supports arm64-v8a, armeabi-v7a, x86, x86_64. Your APK includes compiled native libraries for all four. A user's phone only needs one. So you're shipping 4 apps in one file.

2. The JavaScript engine ships inside your app React Native bundles Hermes on Android as a compiled .so file (~10MB). On iOS, JSC is built into the OS so it's smaller, but Hermes still adds ~2MB if you enable it.

3. Expo SDK native layer Managed Expo links Camera, GPS, Sensors, Haptics, Notifications natively — even if your app never uses them. The JS side is tree-shaken since SDK 54, but the native compiled code is always there.


Who Does the Slimming?

Play Store and App Store do it — you don't.

This is called App Thinning (iOS) and App Bundles (Android). You upload the fat universal binary. The store looks at the user's device, generates a custom version with only what that device needs (right chip, right screen density, right language), and delivers that.

It's not compression. It's surgical removal of everything irrelevant to that specific phone.

This only works if you upload AAB (not APK) on Android.


What You Can Optimize From Your End

1. Switch APK → AAB (biggest single impact)

Upload .aab to Play Store, not .apk. This is what enables per-device slimming. Instant 30-40% reduction in user download size with zero code changes.

In eas.json:

JSON

2. Target Only arm64-v8a (if minSdkVersion ≥ 29)

95%+ of active Android devices are 64-bit. x86 is emulators. armeabi-v7a is pre-2014 devices.

Gradle

Halves your native library footprint.


3. Enable Minification + Resource Shrinking
Gradle

4. Filter Locales

Without this, your app bundles string resources for every language in every dependency (Google Play Services alone has dozens).

Gradle

5. Fix JavaScript Imports

Metro bundles everything transitively imported — even code you never call.

JavaScript

Tree shaking handles ESM-native libraries automatically (SDK 54+), but many libs still need explicit cherry-picking.


6. Strip Console Logs in Production
Bash
JavaScript

Every console.log you wrote is shipped to users otherwise.


7. Assets
  • Convert PNG/JPEG → WebP (25-35% smaller, same quality)
  • Never bundle videos or large audio — load from URL/CDN at runtime
  • Only include font weights you actually render
  • Use vector icons (@expo/vector-icons) instead of multiple PNG sizes

Analyze Your JS Bundle First

Don't optimize blind. Run Atlas and see what's actually large before touching anything.

Bash

Opens an interactive visual map of your bundle — every module, its size, its dependencies. Usually reveals one or two libraries eating 20-30% of the bundle that you forgot about or never needed.

For deeper inspection without Hermes bytecode:

Bash

Priority Order

#ActionImpact
1Upload AAB not APK30-40% download reduction
2Target arm64-v8a only~40% native lib reduction
3Enable shrinkResources + minifyEnabled5-15%
4Filter locales with resConfigs2-5%
5Fix JS imports / remove unused depsvaries, can be large
6Compress/offload assetsvaries, often largest for media apps
7Strip console logsminor

Key Docs

LinkWhat For
docs.expo.dev/distribution/app-sizeAPK vs AAB vs actual download size explained
docs.expo.dev/guides/tree-shakingMetro tree shaking, SDK 54+
docs.expo.dev/guides/analyzing-bundlesExpo Atlas setup
developer.android.com/topic/performance/reduce-apk-sizeGoogle's own guide
developer.apple.com/documentation/xcode/reducing-your-app-s-sizeApple's own guide
callstack.com/blog/optimize-android-application-size-with-gradle-settingsGradle config deep dive