All open-source packages
ToolingSwift

sizeledger

Shows where every megabyte of an iOS app comes from: by category, framework, asset catalog, language and architecture.

1StarsLatest Release: v0.1.10 · Updated: October 21, 2026
Platforms:macOS 13+Linux (x86_64, arm64)

License: MIT

Tests: 159Measured:

How it was measured

swift test in a fresh clone at tag v0.1.10 on a Mac (Apple silicon, Apple M5 Max, macOS 27.0.1), Swift 6.4: 159 tests (134 SizeLedgerKit, 25 CLI), 158 passed and 1 skipped because it needs a non-UTF-8 file name and runs on Linux only

Summary

  • sizeledger reads an .ipa, .app or .xcarchive and shows its bytes by category, framework, language and CPU architecture.
  • It only reads files: it never builds, runs, uploads or changes the app, and gives the same report on macOS and Linux.
  • It keeps three sizes apart: the files added up, an install estimate in 4 KiB blocks and the compressed size inside an .ipa.
  • The ZIP reader, DEFLATE decoder and Mach-O parser are written in Swift, so the SizeLedgerKit library has no dependencies.
  • It does not give the App Store download size, and the diff and budget commands are planned, not shipped, as of 0.1.10.

Point sizeledger at an .ipa, an .app or an .xcarchive and it shows where the app's bytes are: by category, by framework and resource, by language and by CPU architecture. It keeps three sizes apart (the files added up, an install size estimate in whole 4 KiB blocks and, for an .ipa, the compressed size) and does not claim to know the App Store's download size. It reads the files only, with its own ZIP, DEFLATE and Mach-O readers, so it does not build, run, upload or change anything and works the same on macOS and Linux. SizeLedgerKit gives the same report to Swift programs.

Features

  • One table for the whole app: main executable, frameworks and dylibs, app extensions, App Clips, watch app, localizations, asset catalogs, code signature and everything else; the categories always add up to the total
  • Every framework and extension on its own line, and every .lproj language summed across the app and its frameworks
  • Architecture slices of every binary: which binaries are universal and how much each slice takes, with segment sizes and Swift metadata in the JSON
  • Three sizes kept apart: the files added up, an install size estimate in whole 4 KiB blocks and, for an .ipa, the compressed size
  • A terminal table, Markdown for a pull request or job summary, and a JSON report with a stable key order
  • Input treated as untrusted: limits on files, depth, declared bytes and compression ratio, and terminal escapes, bidirectional overrides and invisible characters replaced in the output
  • SizeLedgerKit, a Swift library with DocC documentation and no dependencies: the ZIP reader, DEFLATE decoder and Mach-O parser are part of it

Quickstart

sh
1sizeledger analyze path/to/MyApp.ipa

Installation

Homebrew (macOS, Linux)

sh
1brew install muhittincamdali/tap/sizeledger

From source

sh
1git clone https://github.com/muhittincamdali/sizeledger.git && cd sizeledger && swift build -c release

Swift package (product SizeLedgerKit)

swift
1.package(url: "https://github.com/muhittincamdali/sizeledger", from: "0.1.10")

Screenshots

sizeledger analyze on SampleShop 2.0: 8.75 MB in 21 files, 8.80 MB install estimate, 2.72 MB compressed; catalog.json is 70.8% of the app, Assets.car 18.1%; seven languages; three universal binaries
SampleShop 2.0, the fixture app the tests measure, running in the iOS 27 Simulator

Timeline

  1. Repository opened and 0.1.0 released: sizeledger analyze and the SizeLedgerKit library, with its own ZIP, DEFLATE and Mach-O readers

  2. 0.1.1 to 0.1.5: README in nine languages, bounded Mach-O header reads, symbolic links in an .xcarchive refused, and limits for crafted input (--max-files, --max-bytes, --max-ratio, --max-depth)

  3. 0.1.6 to 0.1.8: Sanitize.text made public, more invisible characters replaced in the output, and paths split and compared on their bytes

  4. 0.1.9 and 0.1.10: overlapping .ipa entries refused as damaged, --out no longer writes through links to files, and the new --force flag

Links

Related Article

Read the article