An all-in-one toolkit for keeping your bundle sizes in check. It ships with a CLI, Node API, and GitHub Action, plus a tester architecture that lets you decide how assets are evaluated.
- Drop-in configuration: define
overweightentries inpackage.jsonoroverweight.config.json. - Works everywhere: CLI, Node API, and an official reusable GitHub Action.
- Extensible testers: start with
gzip(default),brotli, ornone, and plug in your own logic programmatically. - Globs & multi-match aware: every file matched by a glob is tracked individually.
- Conventional commits + semantic-release driven publishing with automatic changelog generation.
- Modern successor to the original
bundlesize: migration is trivial, yet the project stands on its own roadmap.
pnpm add -D overweightKeep your configuration close to your code:
overweight.json(oroverweight.config.json) at the project root (default when the CLI runs without args).package.json→overweightfield (array or object with afilesproperty).- Any JSON file referenced via
overweight --config path/to/config.json.
{
"files": [
{
"path": "./dist/vendor.js",
"maxSize": "30 kB",
"compression": "gzip",
"label": "Vendor bundle"
},
{
"path": "./dist/chunk-*.js",
"maxSize": "10 kB",
"compression": "brotli"
}
]
}Field reference:
| Field | Type | Description |
|---|---|---|
path |
string | File path or glob resolved from the config root. |
maxSize |
string | number | Accepts units (10 kB, 2MiB). Numbers are treated as raw bytes. |
compression |
string | Tester id (gzip, brotli, none). Defaults to gzip. |
label |
string | Optional human-friendly label used in reports. |
pnpm overweight
pnpm overweight --config ./configs/overweight.json
pnpm overweight --reporter json
# quick ad-hoc checks
pnpm overweight --file "dist/*.js" --max-size "15 kB" --compression brotliAvailable reporters: console (default), json, json-file, silent.
# emit a machine-readable report
pnpm overweight --reporter json-file --report-file ./reports/overweight.jsonimport { runChecks, normalizeConfig } from "overweight";
const config = normalizeConfig({
files: [{ path: "./dist/app.js", maxSize: "15 kB", compression: "brotli" }]
});
const result = await runChecks(config, {
testers: {
custom: {
id: "custom",
label: "custom",
async measure(buffer) {
return { bytes: buffer.byteLength / 2 };
}
}
}
});
if (result.stats.hasFailures) {
throw new Error("Bundle too big!");
}name: bundle-overweight-test
on:
pull_request:
push:
branches: [main]
jobs:
overweight:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v3
with:
version: 9
- run: pnpm install
- uses: yoavniran/overweight@v1
with:
config: overweight.json
github-token: ${{ secrets.GITHUB_TOKEN }}
baseline-report-path: overweight-report.json
update-baseline: true
report-file: overweight-report.jsonreport-json,report-table, andreport-fileoutputs enable downstream workflows (PR comments, Slack alerts, artifact uploads, etc.).- When
baseline-report-path+update-baselineare set, the action regenerates the stored bundle size report on a dedicated update branch (not the branch that triggered the workflow). Ifbaseline-report-pathis omitted andreport-fileis set, the baseline defaults to that path. The update runs on a dedicated branch + pull request usingupdate-pr-title,update-pr-body, andupdate-branch-prefix. Usebaseline-protected-branches(defaultmain,master, supports glob patterns) to block updates on protected branches. comment-on-pr-always(first run only) andcomment-on-pr-each-runcontrol when PR comments are posted even if checks pass.- Additional outputs (
report-file,baseline-updated,baseline-update-pr-url,baseline-update-pr-number) make it easy to chain artifact uploads or follow-up workflows.
When update-baseline: true, Overweight will:
- Regenerate the baseline snapshot locally.
- Create a temporary branch from the PR's base branch.
- Commit the updated baseline file with the bot identity.
- Open a pull request targeting the base branch using the configured title/body.
To allow that flow:
- Ensure the workflow grants
contents: writepermission (GitHub defaults to read-only). - Check out the repository with
actions/checkout@v4(fetch-depth defaults are fine because commits are created via the GitHub API). - Pass a
github-tokensecret with permission to create branches and PRs in the repository (the defaultsecrets.GITHUB_TOKENworks for same-repo PRs). - Optionally customize
update-pr-title,update-pr-body, andupdate-branch-prefixto fit your repo conventions. - In the repository settings go to Settings → Actions → General → Workflow permissions and enable Allow GitHub Actions to create and approve pull requests, otherwise GitHub will block the auto-PR.
- Overweight reuses the same update branch/PR per source PR (branch suffix
pr-<number>), so subsequent pushes to your feature branch simply update the existing baseline PR instead of opening multiples. - Use
baseline-protected-branchesto list branches or patterns (comma-separated) where baseline updates are forbidden; the defaultmain,masterprotects the typical default branches. - Manual workflows triggered on a feature branch automatically detect the open PR for that branch and reuse its baseline update PR instead of opening a new one.
- Baseline updates occur only when all size checks pass. Failing runs skip the baseline refresh entirely to avoid locking in broken results.
- The project is ESM-only and built via
tsup - Conventional commits are enforced via
simple-git-hooks+commitlint. pnpm run releasetriggerssemantic-release, which:- Checks commit history,
- Updates the changelog,
- Publishes to npm,
- Creates a GitHub release/tag.
- After each non-dry release run the workflow force-updates a moving major tag (e.g.
v1) so consumers can referenceyoavniran/overweight@v1for the latest release in that major line. .github/workflows/release.ymlexposes adry-runworkflow input (defaults totrue) so manual dispatches preview semantic-release without mutating tags or npm. Set the field tofalseto publish for real, e.g.:
gh workflow run "Overweight Release" \
--ref release-main \
--field dry-run=false
Since the release workflow force-updates major tags (e.g., v1), when syncing your local repository you may encounter tag conflicts. To sync tags properly:
# Recommended: Use the sync-tags script
pnpm run sync-tags
# Or manually force-update all tags from remote
git fetch --tags --force
# Alternative: Delete conflicting tag and re-fetch
git tag -d v1 && git fetch origin tag v1MIT License © Yoav Niran.

