bundle-stats and the problem of comparing two builds you already have
Analyze bundle stats(bundle size, assets, modules, packages) and compare the results between different builds. Support for webpack, rspack, vite, rolldown and rollup.
At a glance
- What is it?
- BundleStats reads the stats file a bundler produces and turns it into a report you can put in front of a reviewer, with bundle size, assets, modules and packages broken out and a side by side comparison between builds. It supports webpack, rspack, vite, rollup and rolldown, and it ships as a set of plugins rather than a single tool.
- Who is it for?
- bundle-stats fits a team that already runs a supported bundler and wants a reviewable report of what changed between two builds, with the plugins wired into an existing build rather than a new tool to learn. It is the wrong choice if you want automatic monitoring on every commit, because that is the hosted relative-ci.com product, and the wrong choice if you need the CLI to accept raw stats without the plugin step, which the documentation does not spell out.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A stats file reader, not a bundler plugin zoo
BundleStats analyses bundle stats, meaning bundle size, assets, modules and packages, and compares the results between different builds. The supported bundlers are webpack, rspack, vite, rollup and rolldown.
The mechanism is worth stating first, because it explains the whole shape of the project. Every one of those bundlers can emit a stats file describing what ended up in the output: which modules, how large, which assets, grouped into chunks and packages. BundleStats does not replace that file. It reads it and renders a report from it.
That design has a direct consequence for how the tool fits into a build. The plugin packages are adapters that produce the stats input, and the analysis and the rendering live in shared packages. The repository is a monorepo of eleven workspaces:
"workspaces": [
"packages/cli",
"packages/cli-utils",
"packages/gatsby-plugin",
"packages/html-templates",
"packages/next-plugin",
"packages/plugin-webpack-filter",
"packages/plugin-webpack-validate",
"packages/rollup-plugin",
"packages/ui",
"packages/utils",
"packages/webpack-plugin"
],The names describe the roles. There is a cli package that generates a bundle stats report, a ui package that renders it, html-templates for the report shell, utils and cli-utils for the shared logic, two webpack specific packages that filter and validate the stats input, and the bundler adapters themselves.
The project is TypeScript, MIT licensed, and the homepage is the metrics and data documentation of relative-ci.com, which is also the commercial product built around the same analysis.
What the report actually shows
The list of report contents in the documentation is the best description of what the tool does, and it is more specific than the word analyzer suggests.
There is bundle size and totals by file type, css, js, img and the rest, so you can see at a glance whether a build grew because of scripts, styles or media. There are insights for duplicate packages and for new packages, which are the two questions a reviewer asks most often when a diff looks large. There are initial JS and CSS metrics, plus cache invalidation, and other bundle metrics grouped together.
Then there are four report views, one per unit of analysis. The assets report covers entrypoint, initial, types, changed and delta. The modules report covers changed, delta, chunks, duplicate count and percentage. The packages report covers count, duplicate, changed and delta.
And there is side by side comparison for multiple builds, which is the feature the project leads with.
The structure is the interesting part. Every report is expressed in the same four terms: the current state, what changed, the delta, and duplication. A report that only showed the current state would be a size report, which any of the bundler analysers already provides. The value of this tool is in the changed and delta columns, and in the duplicate detection, because a bundle that grew by 40 kilobytes is a different conversation from a bundle that grew by 40 kilobytes because the same package now appears twice.
The demos linked from the documentation show the bundle analysis view and the bundle analysis comparison view, which is the shape a reviewer would actually see.
The plugin packages are the integration surface
There is more than one way to get the stats in, and the package list is how you choose.
The webpack plugin generates a bundle stats report for webpack and rspack, and the rollup plugin does the same for rollup, which covers vite since vite builds on rollup. There are also framework specific adapters: a Gatsby plugin for bundle-stats, and a Next.js plugin for bundle-stats, both of which wrap the webpack plugin.
That set of adapters is what makes the tool usable in a real application rather than a demo. A Gatsby site is not going to hand you a stats file, and a Next.js project has its own build wiring, so the plugin for that framework is the integration point.
The two webpack specific packages are worth noticing because they describe what happens to the input. A filter package and a validate package sit between the raw webpack output and the analysis, which suggests the tool does not take the stats file at face value. Bundler stats are famously noisy, containing dev-server and hot module reload entries, and anything that reports on them has to decide what to drop.
The CLI package is the other route, generating a bundle stats report without a build plugin, and the cli-utils package holds its shared helpers.
The related projects section points to two more ways in. There is a GitHub Action, bundle-stats-action, that generates bundle-stats reports, which is how you would get a report in CI without touching the build configuration. And there is relative-ci/compare, a standalone web application to compare webpack, Lighthouse and Browsertime stats, hosted at compare.relative-ci.com, which is a separate use of the same comparison idea.
The hosted product is where monitoring lives
The open source library and the commercial service are adjacent but do different things, and the README is clear about the division.
The hosted service at relative-ci.com is described as automated bundle analysis, reviews and monitoring, with the promise of quickly identifying and fixing bundle regressions before shipping to production. Its feature list mentions in-depth bundle stats analysis for every build, monitoring of bundle stats changes to identify optimization opportunities, and quick feedback through a rule based automated review flow, GitHub Pull Request comments, GitHub check reports, or Slack messages.
It also lists the same broad compatibility that the library has, with support for webpack, vite, rspack, rollup and rolldown, support for all major CI services including CircleCI, GitHub Actions, Gitlab CI, Jenkins and Travis CI, and support for npm, yarn and pnpm including monorepos. The service is described as always free for open source.
The difference in approach matters for the adoption decision. The library is a report generator you run and publish. The service is a monitoring system that watches every build, compares it against a baseline and pushes a comment or a check status back into your workflow. If what you want is a number in a pull request that a reviewer has to think about, the library plus the GitHub Action is enough. If you want the check to fail when the bundle grows, that is the hosted product's job.
A caveat on the service: it is a commercial offering, and the tool being MIT licensed does not make the monitoring free. The pricing page is not described in the project documentation, so anyone evaluating the service needs to look at relative-ci.com directly rather than assume.
Node 14, a Lerna monorepo and a Verdaccio registry in the repo
The root package.json describes a Lerna managed workspace, and the toolchain is worth a look before you adopt it.
The declared engine is Node 14 or newer, and the workspace root is marked private. The build script runs the build across every package through lerna, and the repository also carries a lerna.json, a package-lock.json, a verdaccio.yaml, a .nvmrc, a .husky directory, lint-staged and prettier configuration, and a babel config.
The Verdaccio configuration is the detail that catches the eye. Verdaccio is a local npm registry, and its presence in the repository suggests the packages are published and tested against a local registry rather than against the public npm, which is a common pattern for a multi-package project where one package depends on another at a version that is not yet published.
The dev dependencies describe the test approach. Vitest appears with a browser mode and a playwright driver, so the UI package is tested in a real browser rather than in a jsdom approximation. Playwright itself is present, along with wait-on, which is the tool for waiting on a server to start before running browser tests. There is an eslint configuration that pulls in the airbnb config, the prettier config and a set of plugins for import resolution, react and accessibility.
The fixtures directory and the scripts directory at the root point to a project that tests against sample builds, which is the right way to build an analyser whose whole job is parsing other people's output.
Where bundle-stats is the wrong tool
The first wrong case is wanting continuous monitoring without running a service. The library produces a report; it does not decide whether a build is acceptable, and it does not push anything back into your pull request. That is the hosted product's job, and if your requirement is a check that fails on a regression, you need either that service or you need to write the comparison and the threshold yourself against the report output.
The second wrong case is a bundler that is not in the list. The supported set is webpack, rspack, vite, rollup and rolldown. A project on esbuild or Parcel or a custom build pipeline produces a different artifact, and this tool has no adapter for it. The choice of adapters is also why the tool follows bundler releases closely, since a stats format change upstream is a parsing problem here.
The third wrong case is a team that wants a one-off size report with no history. That is what a bundler's own analyser does, and it does it inside the build you are already running. BundleStats earns its place when you want to compare two specific builds, when you want the same report shape across webpack and vite in a monorepo, or when you want the report in a format you can post in a pull request.
The alternative worth naming is a size budget check in your own CI, which is a smaller piece of work. If the only thing you need is a number compared against a threshold, reading the stats file in a short script and failing the build is a fraction of the dependency, and it gives you exactly the rule you want rather than a general report. The difference in approach is that bundle-stats is a reporting layer that standardises the output across bundlers and lets you diff two arbitrary builds, while a budget check is a policy expressed in code. If you only need the policy, the script is the cheaper answer. If you need the report to argue about, the tool is the one you want.
Maintenance state and what a consumer inherits
The repository is not archived and the last push was on 2026-10-20, which is recent. The tagged releases show a steady cadence: v4.22.1 on 2026-04-14, v4.22.2 on 2026-05-28 and v4.22.3 on 2026-08-22. The versioning is a plain 4.x line, and the patch numbering is what carries the fixes, since a bundler compatibility change has to land somewhere and a patch release is the least disruptive place for it.
The licence is MIT, with the licence text in a LICENSE.md file at the repository root. For a build tool that runs in CI and reads your stats output, the permissive terms mean you can vendor it, wrap it, or reimplement its reports without a licensing conversation.
The upgrade cost is low, and that is the main practical point. The tool is a set of npm packages that you add to a build configuration, so upgrading is a dependency bump rather than a migration. There is no schema to rewrite and no data to convert, because the stats files are produced by the bundler and the report is regenerated from scratch each time.
What you do inherit is a dependency on the tool tracking your bundler. That is not a criticism so much as a fact about the design: the value of the tool is in parsing the stats format of a specific bundler accurately, and bundlers change their stats output as they change their internals. A team that upgrades its bundler aggressively should watch the release notes of this project alongside its own, and a team that has settled on one bundler can relax.
Editorial conclusion
bundle-stats fits a team that already runs a supported bundler and wants a reviewable report of what changed between two builds, with the plugins wired into an existing build rather than a new tool to learn. It is the wrong choice if you want automatic monitoring on every commit, because that is the hosted relative-ci.com product, and the wrong choice if you need the CLI to accept raw stats without the plugin step, which the documentation does not spell out. Before you adopt it, check the plugin list against your bundler, confirm the Node engine requirement of 14 or newer matches your CI images, and read the metrics documentation to see whether the report fields match what your reviewers actually ask about.
Frequently asked questions
What is bundle-stats and which bundlers does it support?
BundleStats analyses bundle stats, meaning bundle size, assets, modules and packages, and compares results between different builds. It supports webpack, rspack, vite, rollup and rolldown.
Which packages does the bundle-stats project publish?
The repository is a monorepo with workspaces for a CLI, cli-utils, a Gatsby plugin, html-templates, a Next.js plugin, a webpack filter package, a webpack validate package, a rollup plugin, a UI package, utils and a webpack plugin.
Does bundle-stats monitor builds automatically?
The open source packages generate a report you run yourself, and a GitHub Action is available to generate reports in CI. Automatic monitoring, review flows and GitHub comments are features of the hosted relative-ci.com product.
What does the bundle-stats report contain?
Bundle size and totals by file type, insights for duplicate and new packages, initial JS and CSS metrics, cache invalidation, and separate reports for assets, modules and packages, each showing current state, changed files, delta and duplication counts, plus side by side comparison of multiple builds.
What Node version does bundle-stats require?
The root package.json declares engines with node 14 or newer. The repository also carries a .nvmrc file, so the intended development runtime is pinned there as well.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/relative-ci-bundle-stats)Was this useful?