Unused Frameworks
iOSDynamic frameworks embedded in the app that are never loaded at runtime. Each adds 0.8-3 MB of dead weight.
Dynamic frameworks embedded in the Frameworks/ directory that are not actually linked or referenced by the main binary or any other framework. Unlike static libraries where the linker performs dead code stripping, dynamic frameworks are included in full because the linker cannot know at build time which symbols will be called at runtime.
Why this happens
Transitive dependencies from package managers. A single high-level SDK (Firebase, analytics suite) pulls in dozens of sub-frameworks. Developers may only use a fraction.
Legacy code and feature flags. Frameworks added for features that were later removed or gated behind disabled feature flags remain linked and embedded.
Conditional compilation (#if directives) only affects source code. Frameworks listed in "Link Binary With Libraries" and "Embed Frameworks" build phases are included regardless.
Build configuration drift. Merge conflicts in .xcodeproj or Podfile.lock reintroduce removed dependencies.
Size impact
Each unused dynamic framework adds 0.8 to 3 MB on average.
Typical range
8-22% binary size decrease after cleanup
Halodoc
~150 MB reduced, ~25% download size reduction
DEAD_CODE_STRIPPING alone
Up to 15% reduction in large projects
Link-Time Optimization
Up to 18% additional reduction
How we detect it
Scans framework dependencies from the main Mach-O binary, builds a complete dependency graph, and identifies frameworks found in the bundle but not linked by the main binary or any other framework.
How to fix
1
Remove from Xcode build phases
Under "Link Binary With Libraries" and "Embed Frameworks", remove unneeded frameworks.
2
Enable dead code stripping
Set DEAD_CODE_STRIPPING=YES (default for Release configurations).
3
Enable Link-Time Optimization
Set LLVM_LTO=YES for cross-module dead code elimination.
4
Review the -ObjC linker flag
This flag forces loading ALL Objective-C code from static libraries, bypassing dead code stripping. Replace with -force_load for specific libraries that need it.
5
Convert dynamic to static frameworks
Static linking enables linker-level dead code elimination.
Podfile
use_frameworks! :linkage => :static6
Use Mergeable Libraries (Xcode 15+)
Set MERGEABLE_LIBRARY=YES on framework targets. This gives you the dynamic-framework developer experience during Debug with static-library optimization in Release.
Important: Apple recommends keeping embedded dynamic frameworks to approximately 6 or fewer to minimize dyld launch overhead.
Powered by Bitrise, trusted by 8,500+ brands
Size Analyzer is built by Bitrise, the leading mobile DevOps platform used by over 400,000 developers at companies like Shopify, TripAdvisor, and BuzzFeed. Free forever. No signup required.
Bitrise provides a full-stack mobile DevOps solution that unites the tools, processes, and testing frameworks engineering teams need to ship best-in-class mobile experiences.