# react-native-bundle-visualizer: finding the one import that bloats your bundle

> react-native-bundle-visualizer drives the Metro bundler and hands the resulting source map to source-map-explorer so you can see which package is responsible for the bytes. It is a small CLI with one job, and the interesting decisions are in its output formats and its handling of broken source maps.

**callstack/react-native-bundle-visualizer** — See what packages are increasing your react-native bundle size 📦

- Repository: https://github.com/callstack/react-native-bundle-visualizer
- Stars: 1,632 · Forks: 50
- Language: Unknown
- License: MIT
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/callstack-react-native-bundle-visualizer

## The problem is one dependency you did not notice

The failure this project addresses is specific and common. Sometimes, importing a single JavaScript library can drastically increase your bundle size, and the library responsible is rarely obvious from the import statement that pulled it in. A transitively imported utility, a date library that also drags in a locale bundle, an icon set that ships every glyph, any of these can move a number on a build dashboard without a matching change in your own code.

react-native-bundle-visualizer exists to turn that unknown into a name. Its description is to see what packages are increasing your react-native bundle size, and the README frames the goal as keeping the bundle size low and loading times fast.

The audience is a React Native or Expo developer doing release work, not a general web developer. The tool is a command line program in the project directory, it reads your real project configuration, and it produces a report. The repository topics list bundle-size, bundle-visualizer, expo and react-native, and the package ships a single binary entry at ./src/react-native-bundle-visualizer.js with the dependencies chalk, execa, minimist, open and source-map-explorer.

The Node requirement is explicit in the package metadata, which declares engines node >= 20. That is a real constraint for teams still on Node 18, and it is stated rather than discovered.

## It is a Metro driver wrapped around source-map-explorer

The mechanism is a pipeline with two stages, and the README names both of them. The tool uses source-map-explorer to visualize the output of the Metro bundler.

So the tool does not analyse your source code. It asks Metro to produce a production bundle with a source map, and then it hands the pair to source-map-explorer, which maps the bytes in the final bundle back to the modules that produced them. The visualizer is the part that runs the build and arranges the output; the analysis is source-map-explorer's work, and the README links to its options page for the format details.

Two consequences follow from that division. First, the tool inherits source-map-explorer's behaviour and its failure modes, including the border checks that the README describes as invalid mapping column and line checks. Second, because the analysis is of a source map, the output is a module level attribution of bytes rather than a dependency tree. It answers which files and packages contributed how much, not which package in package.json pulled in which other package.

The dependency list reinforces the shape of the tool. execa runs the child processes, minimist parses the command line arguments, chalk colours the console output, and open is there to open the generated report in the default browser. There is no database, no server and no upload of your bundle to a remote service, which is the part that makes it usable on a proprietary application at all.

## Running it with npx, and the two flags that matter most

The recommended way to run the visualizer is with npx, and the README gives the React Native and Expo invocations side by side:

```bash
# React Native 0.72+
npx react-native-bundle-visualizer@latest
# or Expo SDK 50+
npx react-native-bundle-visualizer@latest --expo
```

The two comments are the compatibility statement, and they are the first thing to check against your project. The Expo flag is what tells the tool to build an Expo project rather than a bare React Native one, and the README is explicit that the flag is not required for the React Native CLI.

If you would rather have it in the project, it installs as a development dependency:

```bash
yarn add --dev react-native-bundle-visualizer
# or npm
npm install --save-dev react-native-bundle-visualizer
```

and then runs from the local install with either npx react-native-bundle-visualizer or yarn run react-native-bundle-visualizer, depending on the package manager.

All command line arguments are optional, and the defaults are the ones you want most of the time. The platform defaults to ios, the build defaults to production rather than dev, the bundle output defaults to tmp, the entry file is auto resolved when it is omitted, and the output format defaults to html. Two options are worth knowing before you hit a problem. The only-mapped flag excludes unmapped bytes from the output, which lowers the total below the file size, and the verbose flag dumps additional output to the console. There is also a reset-cache option that removes cached react-native files, which matters when the tool reports a bundle that does not match your code.

## Unmapped bytes are the part of the report you will argue about

One row in the output has its own FAQ entry, and the answer is the one every bundle analyser has to give. The README explains that [unmapped] is code in a final bundle without mapping to original source code, usually generated by bundlers such as Webpack, Metro and Babel.

So [unmapped] is not a library you forgot to remove. It is code that exists in the shipped file and cannot be traced back to a source file, which is why the total shown in the report can exceed the sum of the named packages. The README suggests opening the source maps online with the source map visualization tool to check it, and includes a screenshot where the unmapped code is marked with red borders in the editor.

This matters for how you read the report. If you are looking for the largest single cause of a size regression, the named modules are what you want, and only-mapped is the flag to reach for when the unmapped bucket is large enough to hide the answer. If you are trying to account for every byte in the file, the unmapped bucket is part of the answer, and turning that flag on makes the totals stop reconciling with the file size.

The output format decides who can consume the result. The format option accepts html, json or tsv, and the default is html, which is the report you read in a browser. The json and tsv formats are the ones that matter if you want to diff two builds or plot bundle size over time, because they turn the analysis into data rather than a page.

## InvalidMappingColumn is a broken source map, not a broken tool

The README documents a specific error and its workaround, which is a good sign about how the tool behaves in the field. The error reads that your source map refers to generated column Infinity on line 2, but the source only contains 2075 columns on that line.

The fix the README gives is to run the visualizer with the no-border-checks flag, which disables the invalid mapping column and line checks. The corresponding option in the arguments table is border-checks, described as passing the same flag through to the underlying source-map-explorer, and it defaults to false, meaning no check.

The mechanism behind this is worth understanding. The border checks are a validation that the mapping in the source map points at real positions in the generated file. When a bundler emits a mapping that does not line up, the check fails loudly rather than returning a slightly wrong report. Disabling it produces a usable analysis of the parts that do map, at the cost of accepting that some rows may be wrong.

The important decision is which you would rather have. A report that is complete but not fully checked, or a check that fails and tells you nothing. For a one-off investigation, running with the checks on and reading the error is more informative. For a build pipeline that must not break, the flag is the pragmatic choice, and the README frames it as a thing to try rather than a permanent setting.

## A manual alternative, and a list of alternatives the README does not describe

The README has a question about alternatives and answers it by pointing at its similar projects section, which lists expo-atlas, an alternative called expo-atlas-without-expo, and this package itself. The descriptions there are download badges and links, and the README does not set out how those tools differ in what they measure or how they report it. Anyone choosing between them on the strength of that list alone is choosing on nothing.

The alternative the README does explain is more useful. It points at an online source map visualization tool and tells you that you can open your source maps there and check them. That is a genuinely different approach to the same question, and the difference is where the input comes from. This package builds the bundle for you with Metro and analyses what comes out, so it needs a working React Native or Expo project and it runs a real build. An online source map viewer takes a source map you already have and displays it, so it needs no build and no project, and it works for any source map rather than only Metro output.

The practical division is between investigation and diagnosis. When you want to attribute size inside a live React Native project, the visualizer is the tool, because it owns the build and knows the layout. When you already have a source map and want to look at it, or when you are debugging unmapped code, the online viewer is faster and does not touch the project.

## MIT licensed, Node 20, and a package that publishes only its src directory

The licence is MIT, recorded in the package metadata and in a LICENSE.txt file at the repository root. The package name in package.json is react-native-bundle-visualizer, the author is listed as IjzerenHein, and the repository field points at the IjzerenHein/react-native-bundle-visualizer repository even though the project is hosted under the callstack organisation, which is the usual shape for a project that moved to a company and kept its original authorship record.

The published package is deliberately small. The files array contains only src, so what reaches npm is the source of the CLI and nothing else, while the repository also carries a CHANGELOG.md, a CONTRIBUTION.md, a yarn.lock, a.github directory with the CI workflow badge for test.yml, and a.vscode directory.

The version story is worth noting for anyone pinning. There was a long gap, with v3.1.3 published in 2023-02-13, and then two releases days apart, v3.2.0 on 2026-03-18 and v4.0.0 on 2026-03-19. A major version landing the day after a minor one usually signals a change in requirements rather than a change in features, and in this case the metadata carries the requirement change, with node >= 20 in the engines field. The last push to the repository was on 2026-05-27.

One inconsistency shows up if you try to run the test suite from a fresh clone. The package scripts point at fixture directories:

```json
  "scripts": {
    "test": "yarn test:rn && yarn test:expo",
    "test:rn": "cd test/RN64 && yarn install && npx ../.. && cd ../..",
```

The top level of the repository lists src,.github,.gitignore,.vscode and the metadata files, with no test directory, so those fixtures are either generated or excluded from what the listing shows. Either way, the integration tests are the closest thing the project has to a compatibility check, and they are tied to fixture projects named RN64 and Expo42, which is a useful reminder of how the supported range is pinned in practice.

## Conclusion

Reach for react-native-bundle-visualizer when a React Native bundle has grown unexpectedly and you need to attribute the size to specific packages rather than guess, and prefer the json or tsv output format when you want to track bundle size in CI instead of reading a report by hand. Do not adopt it as a general source map tool, since it always builds the bundle first and assumes a Metro based React Native or Expo project. Before you run it, check that the project is on React Native 0.72 or later or Expo SDK 50 or later, and confirm you are on Node 20 or newer, which the package's engines field requires.

## FAQ

### How do I install and run react-native-bundle-visualizer?

The recommended way is npx react-native-bundle-visualizer@latest, or the same command with --expo for an Expo project. You can also add it as a dev dependency with yarn add --dev react-native-bundle-visualizer and run it from the local install.

### Which React Native and Expo versions does react-native-bundle-visualizer support?

The usage examples in the README are labelled for React Native 0.72+ and Expo SDK 50+, and the README refers to a version compatibility table for the full list. The package also requires Node 20 or newer through its engines field.

### What does [unmapped] mean in the react-native-bundle-visualizer report?

The README defines it as code in a final bundle without a mapping to original source code, usually generated by bundlers such as Webpack, Metro and Babel. The only-mapped flag excludes those bytes from the output, which is why the totals then come out lower than the file size.

### How do I fix the InvalidMappingColumn error in react-native-bundle-visualizer?

The README says to run the visualizer with the --no-border-checks flag, which disables the invalid mapping column and line checks. The checks are passed through to source-map-explorer, which is the tool doing the analysis.

### Can I get the react-native-bundle-visualizer output in a machine readable format?

Yes. The format option accepts html, json or tsv, with html as the default. The json and tsv outputs are the ones to use if you want to compare two builds or track bundle size over time.

## Sources

- [callstack/react-native-bundle-visualizer on GitHub](https://github.com/callstack/react-native-bundle-visualizer)
- [Issues](https://github.com/callstack/react-native-bundle-visualizer/issues)
- [License: MIT](https://github.com/callstack/react-native-bundle-visualizer/blob/main/LICENSE)
- [README](https://github.com/callstack/react-native-bundle-visualizer/blob/main/README.md)
- [Releases](https://github.com/callstack/react-native-bundle-visualizer/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/callstack-react-native-bundle-visualizer
