Bundle Analysis with CLI
Analyze bundles with the Bundle Drop CLI
Bundle Drop Sight builds and analyzes React Native and Expo bundles, compares Git revisions, and measures emitted assets and Bundle Drop OTA archives. Analysis runs locally in your browser; bundles, source maps, inventories, and Git context are not uploaded to Bundle Drop. No account is needed for analysis.
Prefer your existing React Native or Expo commands? Follow bundle analysis without the CLI.
Quick start from your app
The Sight command ships with @gfean/react-native-bundle-drop. From the app directory containing package.json, use the installed CLI:
npx bundle-drop sight --platform android
npx bundle-drop sight --platform iosSight generates production, minified JavaScript and a matching source map, collects emitted asset sizes, and offers to open the browser for local analysis. It uses the app's installed dependencies; no Xcode or Gradle app build is needed.
Use --project-type expo or --project-type bare if project detection is ambiguous. Bare React Native projects with a custom entry can use --entry-file <path>. Give noninteractive runs an explicit --platform ios or --platform android.
Compare a branch with your current changes
npx bundle-drop sight --compare main --platform android
# Refresh a remote baseline explicitly:
npx bundle-drop sight --compare origin/main --fetch --platform androidThe baseline is the branch, tag, or commit named by --compare. The current build includes uncommitted edits, deletions, and nonignored untracked files. Sight builds sequentially in private snapshots with independently installed dependencies, preserving your original checkout, index, and local branches.
Without --fetch, Sight resolves exactly the ref available locally. main and origin/main are different choices; no remote fetch happens implicitly. With --fetch, name a configured remote branch such as origin/main. Git uses your existing authentication to refresh that branch. Sight does not collect repository credentials.
Both builds use the same platform and logical entry while preserving revision-specific framework, Metro, and Babel configuration. Toolchain changes can affect the comparison alongside source edits.
Installs may download packages and execute project scripts. Each revision needs a consistent lockfile and available compatible package manager. Sight uses frozen installs without repairing lockfiles or replacing tooling.
Include ignored build inputs
Ignored local files are excluded from comparison snapshots by default. If both builds need an ignored environment file, include it explicitly:
npx bundle-drop sight --compare main --platform android --include .env.productionRepeat --include <path> for additional exact files or directories, relative to the app directory. Sight captures each included input once and copies it identically to both builds. Inputs must stay inside the repository and cannot overwrite tracked files on either revision, manifests, lockfiles, Git administration, or installed dependencies.
Builds that inspect Git
Both private checkouts have detached HEAD: baseline retains its resolved commit; current retains your original HEAD with captured working-tree edits. History and tags reflect the locally available Git view, so shallow history can affect git describe. Original branch labels appear as context, but staging partitions are not reproduced. Branch- or staging-dependent builds must account for these semantics.
Explore the results
Inspect packages and source files in searchable tables and treemaps. Compare mode shows additions, removals, and signed byte changes. Read JavaScript size and attribution for what these metrics include.
Bundled assets
CLI analysis includes a Bundled assets table below the package and file results when emitted assets are present. It shows raw file sizes for images, fonts, and other outputs emitted by Metro or Expo for the selected platform. Manual analysis does not show this table.
Each emitted output path is counted once. Density variants and identical bytes emitted at different paths count separately. Native-only resources and files downloaded from remote URLs are outside this inventory.
Asset comparisons match output-relative paths and content hashes. A file whose content changes without changing size still appears as changed; a renamed output appears as removed and added. Search the asset table or select Changed to narrow the results. Asset totals remain separate from JavaScript totals.
The browser receives paths, lengths, and hashes, rather than asset binaries.
Bundle Drop OTA size
Bundle Drop OTA size is the measured size of a full Bundle Drop OTA archive. It includes the runtime bundle, emitted assets, and delivery metadata, and excludes source maps, native-only resources, and remote assets.
Sight uses Hermes bytecode when enabled, JavaScript otherwise, with project-local compiler tooling. Compilation and compression add work after JavaScript bundling, once in single mode and once per side in Compare mode. Expo's Hermes path needs a separate bytecode export to match its upload pipeline.
Single analysis displays the archive size. Compare mode leads with the signed archive-size difference and keeps current and baseline sizes below it. This comparison requires Bundle Drop configured on both branches, with resolvable app and runtime versions and the necessary compiler.
If one side cannot be measured, Sight explains why and does not invent a difference. JavaScript and asset comparisons remain usable, including when a baseline predates the Bundle Drop configuration. Manual uploads and older CLI output show the OTA metric as unavailable; they do not receive an estimated total.
The measurement uses Sight's selected entry and build environment. Different upload overrides or inputs can change the final archive size. It represents the full Bundle Drop OTA archive, rather than a patch update.
Keep generated files and recover a local session
npx bundle-drop sight --platform android --no-open --output ./sight-analysis
npx bundle-drop sight --compare main --platform android --no-open --output ./sight-comparisonChoose a new or empty output directory. --output <path> keeps generated files there. --keep retains files after successful automatic loading, and --no-open skips the browser handoff. A failed handoff also preserves valid artifacts for manual use.
Single analysis retains the bundle/map pair and analysis-assets.json. Comparison output contains baseline/ and current/ bundle/map pairs, plus comparison.json and comparison-assets.json. These JSON files are local records that bind the measured context to the generated files; they are not manual upload inputs.
Recover manual JavaScript analysis by selecting the retained bundle/map files. Rerun with browser opening enabled to restore assets and Git context. Changing a build file or resetting clears CLI context. Private snapshots are cleaned up after comparison; uncatchable termination can leave temporary directories.
Export results
Export local HTML, PDF, Markdown, or JSON reports. Single analysis also supports PNG and SVG. Reports include available asset and OTA measurements; comparison summaries lead with the OTA size change. See export formats and report limits.
Requirements and current limits
Comparison requires an existing Git commit, no unresolved conflicts, the app manifest, and usable lockfiles. Standalone apps and in-repository workspaces are supported layouts. Required inputs must be available inside the repository; workspace siblings are preserved for the build.
The comparison implementation targets npm, pnpm, Yarn Classic, and modern Yarn with node-modules. Bun, Yarn PnP, sparse/partial clones, external required dependencies, and required inputs relying on submodules, Git LFS, or custom checkout filters are outside the current comparison scope. Sight rejects detectable blocking layouts before expensive build work.
Real end-to-end verification has run on macOS with bare React Native and Expo, including iOS and Android JavaScript output. Independent install fixtures have exercised npm, pnpm, Yarn Classic, and modern Yarn. This is not a full framework/package-manager matrix: native Windows and Linux execution, and full framework builds for every manager and workspace layout, remain unverified.
Troubleshooting
Bundle Drop OTA size is unavailable. Read the card's reason. Check the analyzed revision's Bundle Drop runtime configuration, app version, engine setting, and local compiler. In comparison mode, check both revisions independently; successful measurement of the current branch does not supply missing baseline configuration.
A comparison install fails. Reproduce its frozen install with the declared package-manager version. Supply registry authentication through your normal environment, and correct dependency or lockfile issues without bypassing checks.
A baseline is missing or stale. Choose the intended local ref or explicitly fetch a remote branch. Detached HEAD and shallow clones work when required objects are available.
An ignored file is needed. Use --include with its app-relative path. Correct tracked-file collisions or escaping paths rather than overriding protected files.
The browser cannot connect to the CLI. Keep the terminal process running during handoff. Use the retained files for manual JavaScript analysis, or rerun with automatic browser opening to recover the CLI-only measurements.
