base-lint
v1.2.1
Published
Lint your repo against Web Baseline policies
Maintainers
Readme
base-lint CLI
base-lint scans your repository for usage of modern Web Platform features and evaluates them against the Baseline dataset. Use it locally or in CI to make sure new features ship with fallbacks.
Why base-lint?
- Catch Baseline gaps before they reach production by enforcing fallbacks in pull requests.
- Share actionable Markdown summaries and GitHub Checks so reviewers see the same findings.
- Automate regression protection in CI by failing builds when new incompatibilities appear.
Table of contents
Prerequisites
- Node.js 18.17+ or 20.x LTS.
- Git.
- TypeScript compatibility.
base-lintrelies on@typescript-eslint/typescript-estreeto parse TypeScript and JavaScript sources. The CLI suppresses the parser's unsupported TypeScript version banner by default, but effective compatibility remains tied to the versions that@typescript-eslint/typescript-estreesupports. Using newer or older TypeScript releases may lead to parsing errors until they are adopted by the upstream parser.
Quick start
Minimal workflow
Install the CLI (development dependency is typical for CI):
npm install --save-dev base-lintScan your repository (diff mode is the default so you focus on the changes under review):
npx base-lint scan💡 Diff vs. full scan: Pass
--mode=repoto analyze the entire codebase, which is helpful for scheduled audits or first-time rollouts.Interpret the results from the generated Markdown summary (a condensed version prints to the terminal after each scan):
cat .base-lint-report/report.md- Pass
--print-full-reporttoscanto stream the entire Markdown table to stdout. - The Markdown file includes a status badge and tables you can paste into pull requests.
- The accompanying
report.jsonis consumable by automation (seeenforce).
- Pass
✅ CI tip: Cache
.base-lint-report/between jobs soenforce,annotate, andcommentcan reuse the same scan output without rerunning analysis.
Command cheat sheet
base-lint scan– Collect findings in JSON/Markdown for local or CI use.base-lint enforce– Fail fast in CI when findings exceed your thresholds.base-lint annotate– Upload inline GitHub Checks from the latest scan.base-lint comment– Maintain a sticky PR summary comment.base-lint init– Scaffold config, ignore rules, and a starter GitHub Action.base-lint clean– Remove generated report artifacts between runs.
Installation
Install the CLI as a development dependency with your package manager of choice:
npm
npm install --save-dev base-lintpnpm
pnpm add -D base-lintYarn
yarn add --dev base-lintRun npx base-lint --help (or the package manager equivalent) for the full flag list.
Detailed commands
base-lint scan
Analyze your repository (or just the current diff) and emit structured reports.
npx base-lint scanBy default the CLI outputs to .base-lint-report/ in the current working directory. Every run writes report.json, report.md, and meta.json, then prints both a condensed Markdown summary (or the full table with --print-full-report) and the folder location to stdout. The Markdown report includes a status summary and a table of findings that you can link from PR descriptions or surface in GitHub comments.
| Flag | Default | Description |
| --- | --- | --- |
| --mode <mode> | diff | Analysis mode (diff or repo). |
| --out <dir> | .base-lint-report | Output directory for generated reports. |
| --out-format <format> | md | Format for stdout or --out-file (md, json, or sarif). |
| --out-file <path> | — | Write the formatted output to a single file instead of stdout. |
| --strict | false | Enables strict feature detection. |
| --treat-newly <behavior> | warn | Controls whether Newly findings warn, error, or are ignored. |
| --config <path> | — | Override path to base-lint.config.json. |
| --print-full-report | false | Prints the full Markdown report to stdout. |
Combine --out-format and --out-file to generate SARIF for GitHub Advanced Security:
npx base-lint scan --mode=repo --out-format=sarif --out-file=.base-lint-report/report.sarifUpload the SARIF artifact with github/codeql-action/upload-sarif so findings surface in Security › Code scanning alerts.
Need to manually verify the formatter behavior? These commands cover the release acceptance criteria:
# Confirm SARIF output over stdout when no --out-file is passed.
npx base-lint scan --out-format sarif | jq '.runs[0].results | length'
# Confirm file emission when requesting JSON.
npx base-lint scan --out-format json --out-file tmp/base-lint/report.json
jq '.summary' tmp/base-lint/report.json
# Confirm init overwrite semantics.
npx base-lint init --forcePrefer to change these defaults globally? See Configuration.
base-lint enforce
Gate your CI workflow based on the JSON scan results.
npx base-lint enforcebase-lint enforce automatically reads .base-lint-report/report.json. If scan writes to a custom --out, pass the matching --input when enforcing (for example, base-lint enforce --input custom-dir/report.json).
--max-limited defaults to 0, so the command fails if any Limited findings remain. Set --fail-on-warn (or configure treatNewlyAs: "error") when Newly findings should also block merges.
| Flag | Default | Description |
| --- | --- | --- |
| --input <file> | .base-lint-report/report.json | JSON report emitted by scan (override when scan --out changes). |
| --max-limited <count> | 0 | Maximum allowed Limited findings before failing. |
| --fail-on-warn | false | Treat Newly findings as failures. |
Prefer to change these defaults globally? See Configuration.
📈 CI usage: Run
scanonce per workflow and reuse its artifacts in separateenforce,annotate, orcommentjobs to avoid redundant analysis time.
Exit codes
scan and enforce share the same policy helper so automation can key off the exit code. When a policy fails the CLI prints a short explanation and sets a non-zero exit code that maps directly to your Baseline thresholds:
| Code | Meaning | Policy source |
| --- | --- | --- |
| 0 | Baseline policy satisfied. | Findings remain within configured thresholds. |
| 1 | Limited findings exceeded the allowed maximum. | maxLimited from config or --max-limited. |
| 2 | Newly findings treated as errors. | treatNewlyAs: "error" or --fail-on-warn. |
| 3 | Internal error (unexpected failure). | Invalid input, missing reports, or unhandled exceptions. |
base-lint annotate
Create or update a GitHub Check run with inline annotations from the scan.
npx base-lint annotate --input .base-lint-report/report.jsonThe command detects GITHUB_TOKEN/GH_TOKEN, GITHUB_REPOSITORY, and GITHUB_SHA to decide whether it can contact the GitHub Checks API; when any of them are missing (for example, when running locally) the command exits quietly. In pull-request workflows, it skips forks for safety and uploads annotations in batches of 50 by default. The resulting Check run links back to the Markdown table generated by scan, making it easy to jump into detailed findings.
ℹ️ GitHub Actions context:
- Required environment variables:
GITHUB_TOKEN(orGH_TOKEN),GITHUB_REPOSITORY, andGITHUB_SHAso the CLI knows where to post the Check run.- GitHub-hosted runners inject these automatically, minting
GITHUB_TOKENfor each workflow (see the GitHub Action example andpackages/action/README.mdfor why forked pull requests are skipped).- Self-hosted runners or alternative CI providers can pass a fine-scoped personal access token as
GITHUB_TOKENvia encrypted secrets; avoid echoing tokens to logs.
| Flag | Default | Description |
| --- | --- | --- |
| --input <file> | Required | JSON report emitted by scan. |
| --batch-size <n> | 50 | Number of annotations sent per API request. |
Prefer to change these defaults globally? See Configuration.
base-lint comment
Maintain a sticky pull request summary comment that mirrors the Markdown report.
npx base-lint comment --input .base-lint-report/report.mdThe CLI reads the Markdown file, looks for GITHUB_TOKEN, GITHUB_REPOSITORY, and GITHUB_EVENT_NAME, and only posts to pull-request events to avoid noise on other triggers. Existing comments containing the <!-- base-lint-sticky --> marker are updated in place; otherwise a new comment is created.
ℹ️ GitHub Actions context:
- Required environment variables:
GITHUB_TOKEN,GITHUB_REPOSITORY, andGITHUB_EVENT_NAME(must bepull_request*) so the CLI can update the sticky comment.- GitHub-hosted runners provide these automatically, with
GITHUB_TOKENissued per workflow (see the GitHub Action example andpackages/action/README.mdfor token scope details and fork safeguards).- In self-hosted or alternative CI, source a personal access token securely (for example, via masked secrets) and export it as
GITHUB_TOKEN/GH_TOKENbefore running the command.
| Flag | Default | Description |
| --- | --- | --- |
| --input <file> | Required | Markdown report emitted by scan. |
| --sticky-marker <marker> | <!-- base-lint-sticky --> | HTML marker used to find or create the sticky comment. |
Prefer to change these defaults globally? See Configuration.
base-lint init
Bootstrap a repository with sensible defaults for configuration, ignore rules, and CI wiring.
npx base-lint initThe command writes base-lint.config.json, .base-lintignore, and .github/workflows/base-lint.yml when they are absent. Existing files are preserved unless you re-run with --force, which overwrites them after logging the action so you can review the diff.
| Flag | Default | Description |
| --- | --- | --- |
| --force | false | Overwrite existing files instead of skipping them. |
Add the generated files to version control once you have tailored them to your workflow.
base-lint clean
Delete the generated report directory (default: .base-lint-report/) to start fresh.
npx base-lint cleanThe command removes the configured directory with rm -rf semantics and logs the result. Pair it with scan in CI workflows that prefer ephemeral artifacts or when switching between branches locally to avoid stale reports.
| Flag | Default | Description |
| --- | --- | --- |
| --out <dir> | .base-lint-report | Report directory to delete. |
Prefer to change these defaults globally? See Configuration.
Advanced usage
Dive deeper into configuration and automation patterns once the basics are in place.
Configuration
base-lint.config.json– Optional configuration file resolved from the repository root (or the path you pass to--config).mode(default:"diff") – Scan only the current Git diff ("diff") or the entire repository ("repo"). Diff mode keeps PR noise low; repo mode suits full audits and rollouts.treatNewlyAs(default:"warn") – Control how Newly Baseline findings behave. Pick"warn"to surface issues without failing,"error"to block merges, or"ignore"when you only care about Limited features.maxLimited(default:0) – Maximum Limited findings tolerated bybase-lint enforce. Increase it to phase Base Lint in while you fix legacy gaps.strict(default:false) – Enable stricter detection heuristics (for example, computed property access). Useful when you want the strongest signal, otherwise leave off to avoid noisy dynamic cases.targets(default:"all") – Reserved for upcoming Baseline targeting controls. Stick with the default unless you are experimenting with pre-release dataset filters.suppress(default:[]) – List Baseline feature IDs to mute after you have documented fallbacks or accepted the risk.include(default:[]) – Glob patterns that act as an allowlist. Empty means “consider everything the mode collects”; provide paths such as"src/**/*"to narrow the scan.ignore(default:[]) – Additional ignore globs that apply to all runs. These are added on top of the built-in defaults and anything in.base-lintignore.
.base-lintignore– Optional ignore file that uses.gitignoresemantics. Base Lint appends its entries to the core defaults and config ignores during resolution (seepackages/cli/src/config.ts).
Default ignore entries:
node_modules/
dist/
build/
coverage/
*.min.jsExample .base-lintignore snippet:
# Skip generated Storybook output checked into docs
storybook-static/
# Drop vendored playground builds
apps/*/sandbox/dist/Use the ignore array in base-lint.config.json for repository-wide exclusions that every environment should share, and reserve .base-lintignore for local or ephemeral directories that individual developers need to silence without editing the shared config.
Configuration files override the CLI defaults, and direct flags always win over configuration. For full option descriptions and additional examples, see the Base Lint configuration guide.
