Audit npm package bundle sizes against gzip budgets in CI.
This action sends an exact name@version package list to the BundleCheck API, reports per-package and total gzip size, posts or updates a PR comment, and can fail the workflow when budgets are exceeded.
- Audits exact npm package versions (for example
react@18.2.0) - Enforces optional budgets:
- per package (
per_package_gzip) - total sum (
total_gzip)
- per package (
- Supports async processing for large package lists
- Upserts a single PR comment with results
- Exposes outputs for downstream workflow steps
| Input | Required | Default | Description |
|---|---|---|---|
api_key |
Yes | - | BundleCheck API key (X-API-Key) |
packages |
No | - | Newline-separated exact name@version list. When omitted, the action runs in lockfile compare mode. |
per_package_gzip |
No | - | Per-package gzip budget in bytes |
total_gzip |
No | - | Total gzip budget in bytes (sum of individual package costs) |
fail_on_violation |
No | true |
Fail when budget violations are found |
fail_on_partial |
No | false |
Fail when any package could not be bundled (denied, not_found, timeout, error) |
warn_only |
No | false |
Always exit 0 even if violations are found |
github_token |
No | ${{ github.token }} |
Token used to post/update PR comment |
api_url |
No | https://bundlecheck.dev |
Override API base URL |
poll_interval_seconds |
No | 3 |
Poll interval for async audits |
poll_timeout_seconds |
No | 300 |
Max wait time for async audits |
lockfile_path |
No | package-lock.json |
Path to lockfile relative to repo root (lockfile compare mode only) |
base_ref |
No | PR base branch | Git ref to diff against (lockfile compare mode only) |
| Output | Description |
|---|---|
pass |
true or false based on audit result |
total_gzip |
Sum of gzip sizes across successfully bundled packages (bytes) |
violation_count |
Number of per-package violations (excludes total line item) |
name: BundleCheck
on:
pull_request:
permissions:
contents: read
pull-requests: write
jobs:
bundlecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run BundleCheck audit
id: audit
uses: venwork-dev/bundlecheck-audit-action@v1
with:
api_key: ${{ secrets.BUNDLECHECK_API_KEY }}
packages: |
react@18.2.0
axios@1.6.7
per_package_gzip: 50000
total_gzip: 120000
fail_on_violation: true
fail_on_partial: false
warn_only: false
- name: Print summary
run: |
echo "pass=${{ steps.audit.outputs.pass }}"
echo "total_gzip=${{ steps.audit.outputs.total_gzip }}"
echo "violations=${{ steps.audit.outputs.violation_count }}"The action needs pull-requests: write to post or update the PR comment. Add this to your workflow:
permissions:
contents: read
pull-requests: writeWithout it the audit still runs and the workflow result is correct, but no comment will appear on the PR.
total_gzipis the sum of individual package costs. It is not your real app bundle size (no deduplication/tree-shaking modeling).- For large batches, the API may return
202and the action will poll until completion. - Outside pull request context, the action logs the rendered report instead of posting a PR comment.
Use major tags in consumer workflows:
uses: venwork-dev/bundlecheck-audit-action@v1This repository publishes immutable release tags (vX.Y.Z) and keeps the floating major tag (vX) updated to the latest compatible release.
Use the Release workflow in this repository:
- Run
Releaseviaworkflow_dispatch - Provide a semantic version (
1.2.3orv1.2.3)
The workflow will:
- Rebuild
dist/ - Commit
dist/tomainif needed - Create immutable tag
vX.Y.Z - Update floating major tag
vX - Create a GitHub Release with generated notes
Marketplace publication is a manual GitHub UI step on the created release.
bun install
bun run typecheck
bun run builddist/index.js is committed for GitHub Action runtime consumption.