Unnecessary Build Artifacts

iOS & Android

Development-time files (headers, module maps, Swift modules, READMEs) shipping in production builds. Also a security concern per OWASP guidelines.

Development-time files that serve no runtime purpose shipping in production app bundles. These include module.modulemap, .swiftmodule, .swiftdoc, header files (.h/.hpp), README/CHANGELOG, .gitkeep, .bcsymbolmap (fully deprecated in Xcode 16), and build scripts like strip-frameworks.sh.


Why this happens

  • Vendored frameworks shipped with headers, module maps, documentation, and build scripts inside the .framework bundle.

  • CocoaPods resource copying. The "resources" attribute copies files without filtering development artifacts.

  • Carthage historically did not strip Swift modules or all metadata from frameworks.

  • Manual framework integration via drag-and-drop includes all directory contents.

  • Incorrect target membership. Files accidentally added to "Copy Bundle Resources" build phase.


Size impact

Beyond wasted space, OWASP MASTG-TEST-0083 classifies shipping headers and module maps as a resilience issue: it transforms reverse engineering from a skilled undertaking into trivially reading well-structured declarations.

Headers (33 dynamic frameworks)

3.8 MB

.swiftmodule files

Several hundred KB per framework

Typical total (20-40 framework deps)

5-15 MB

PackageX iOS SDK (extreme)

550 MB to 15 MB after optimization


How we detect it

Scans all files and matches against known patterns that should not be in production bundles. Files are grouped by removal reason and impact is calculated using disk usage (4 KB blocks).


How to fix

1

Set Xcode build settings for Release

Enable COPY_PHASE_STRIP, DEPLOYMENT_POSTPROCESSING, STRIP_INSTALLED_PRODUCT, and STRIP_SWIFT_SYMBOLS.

2

Add a cleanup build script

Add a Run Script phase after "Embed Frameworks" to remove development files from bundled frameworks.

Run Script (after Embed Frameworks)

find "${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}" \ -name '*.framework' | while read -r framework; do rm -rf "${framework}/Headers" "${framework}/PrivateHeaders" \ "${framework}/Modules" rm -f "${framework}/README"* "${framework}/CHANGELOG"* \ "${framework}/LICENSE"* rm -f "${framework}/"*.sh "${framework}/"*.bcsymbolmap \ "${framework}/.gitkeep" done

3

Switch to static linking

Use use_frameworks! :linkage => :static in CocoaPods to eliminate framework bundles entirely.

4

Use SPM exclude directive

SPM is generally cleaner by default. Use "exclude" in Package.swift to filter unnecessary files from targets.


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.

Bitrise logo