Checks your code for web features that might not be safely supported in your target browsers.
Uses the official web-features
data + your Browserslist or baseline.config.json
.
Author: codewithshinde npm: https://www.npmjs.com/package/baseline-guard GitHub: https://github.com/codewithshinde/baseline-guard
Device power ≠ browser support. A feature like :has()
or RegExp lookbehind can work on your machine but fail on Safari/iOS your users run.
Baseline Guard answers: “Is this feature safe for the browsers we support?”
npm i -D baseline-guard
# or
yarn add -D baseline-guard
# or
pnpm add -D baseline-guard
Requires Node 18+.
- Create
baseline.config.json
at your project root:
{
"targets": ["chrome >= 114", "edge >= 114", "firefox >= 115", "safari >= 17", "ios_saf >= 17"],
"mode": "warn"
}
If you already have Browserslist (in
package.json
or.browserslistrc
), you can omittargets
.
- Add scripts:
{
"scripts": {
"baseline:check": "baseline-guard",
"baseline:report:md": "baseline-guard --report=md --save",
"baseline:report:html": "baseline-guard --report=html --save",
"baseline:report:json": "baseline-guard --report=json --save"
}
}
- Run it:
npm run baseline:check
You’ll get a summary of targets, a rules table, files scanned, and any issues.
-
Scans JS / TS / TSX / CSS / HTML files in your repo.
-
Detects modern features (e.g.,
:has()
, container queries, WebGPU, RegExp lookbehind). -
Checks each feature against:
- Minimum browser versions from
web-features
(per-browser minima), and - Your targets (Browserslist or
baseline.config.json
).
- Minimum browser versions from
-
Prints results to the console and can save Markdown, HTML, or JSON reports.
-
Reports show a compact per-browser summary of failing targets (e.g.,
Safari: requires ≥ 17 (your targets include 16–16.3, 4 versions)
).
baseline-guard
[--list-rules]
[--show-rules | --show-rules=all | --show-rules=checked]
[--pack=core|popular|risky|experimental|all]
[--tags=css,js,html,popular,bug-prone,experimental]
[--only=ruleA,ruleB] [--exclude=ruleC,ruleD]
[--emit-all-rules] [--emit-rule=<web-feature-id>]
[--report=md|html|json] [--out=path] [--save]
- Rules table view:
--show-rules=checked
(only enabled rules). Use--show-rules
or--show-rules=all
to see all rules. - Pack:
all
(when not provided).
Columns: Web Feature ID | Rule | Checked | Rule Type | Tags | Pack
Rows render red when that feature actually produced findings in the scan.
--list-rules
prints the same table (no scan; uses minima-only logic for highlight).
# Show rules (table). Default filters to 'checked' rules:
baseline-guard --list-rules
# Show all rules in the table:
baseline-guard --list-rules --show-rules=all
# Filter by tags or pack:
baseline-guard --list-rules --tags=css
baseline-guard --list-rules --pack=popular
# Run with only a subset of rules (IDs), or exclude some:
baseline-guard --only=css-has,css-container-queries
baseline-guard --exclude=webgpu
# Save a Markdown/HTML/JSON report (to .baseline/ with timestamp):
baseline-guard --report=md --save
baseline-guard --report=html --save
baseline-guard --report=json --save
# Save to a custom path:
baseline-guard --report=html --out .baseline/report.html
# Generate all web-feature-based rules to .baseline/web-feature-rules.json
baseline-guard --emit-all-rules
# Inject a single generated rule into baseline.config.json (rules[])
baseline-guard --emit-rule=css-selector-has
0
= no violations, ormode
is"warn"
.1
= violations exist andmode
is"error"
.
baseline.config.json
→targets
andmode
package.json > baseline.targets
(optional)- Browserslist (
package.json
or.browserslistrc
) - Fallback preset: Chrome/Edge 114, Firefox 115, Safari/iOS 17
Add rules directly inside baseline.config.json
under a rules
array.
Because JSON can’t store RegExp
, provide a pattern
string and optional flags
; the CLI compiles them.
{
"targets": ["chrome >= 114", "edge >= 114", "firefox >= 115", "safari >= 17", "ios_saf >= 17"],
"mode": "warn",
"rules": [
{
"id": "js-regexp-unicode-sets",
"featureId": "js-regexp-unicode-sets",
"files": ["js", "ts", "tsx"],
"pattern": "/[^/]*\\\\p\\{[^}]+\\}[^/]*\\/v",
"flags": "g",
"message": "RegExp Unicode sets (flag v) may not be supported by your targets.",
"tags": ["js", "experimental"]
},
{
"id": "css-custom-prop-register",
"featureId": "css-properties-and-values",
"files": ["css"],
"pattern": "@property\\s+--",
"flags": "g",
"message": "CSS Properties & Values API (@property) may not be in your baseline.",
"tags": ["css", "experimental"]
}
]
}
Notes
id
must be unique. If it matches a built-in rule ID, your inline rule overrides it.featureId
must be a valid web-features ID (e.g.,css-selector-has
,webgpu
,js-regexp-lookbehind
).- Include
"flags": "g"
so the rule can match multiple times per file. - Escape backslashes in JSON:
\\
.
Console: target summary, rules table (with red rows for actual findings), issues. Markdown/HTML reports:
-
Browser Targets: every browser + the exact versions in your targets.
-
Web Features Coverage: same columns as CLI rules table.
-
Issues: compact Unsupported (browser target < min) per browser, e.g.:
Safari: requires ≥ 17.0 (your targets include 16–16.3, 4 versions) iOS Safari: requires ≥ 17.0 (your targets include 16–16.3, 4 versions)
JSON report includes structured data per finding:
{
"file": "src/components/PriceDisplay.tsx",
"line": 12,
"col": 10,
"ruleId": "js-regexp-lookbehind",
"featureId": "js-regexp-lookbehind",
"msg": "RegExp lookbehind may not be supported by your targets.",
"unsupported": [
{ "browser": "safari", "target": "16.3", "min": "17.0" },
{ "browser": "ios_saf", "target": "16.3", "min": "17.0" }
]
}
Create reports:
# Save Markdown/HTML/JSON to .baseline/baseline-report-<timestamp>.<ext>
baseline-guard --report=md --save
baseline-guard --report=html --save
baseline-guard --report=json --save
# Custom path
baseline-guard --report=html --out .baseline/report.html
-
Local dev: run
baseline:check
to spot problems early. -
Pre-commit: block commits that introduce unsupported features.
npx husky init echo 'npm run baseline:check' > .husky/pre-commit
-
CI: fail when violations exist and
mode
is"error"
.- name: Baseline check run: baseline-guard --report=md --save
-
PR reviews: upload the Markdown/HTML report as an artifact.
-
Monorepos: each app can keep its own
baseline.config.json
(or share Browserslist).
Baseline Guard (source: baseline.config.json)
Targets (summary)
┌────────────┬────────────────────┬───────┐
│ Browser │ Versions (min–max) │ Count │
├────────────┼────────────────────┼───────┤
│ Chrome │ 114–140 │ 27 │
│ Edge │ 114–140 │ 27 │
│ Firefox │ 115–143 │ 29 │
│ Safari │ 17–26 │ 14 │
│ iOS Safari │ 17–26 │ 14 │
└────────────┴────────────────────┴───────┘
Rules (pack: all, filtered: checked)
┌────────────────────────────────┬───────────────────────────┬─────────┬───────────┬──────────────────────────────┬──────┐
│ Web Feature ID │ Rule │ Checked │ Rule Type │ Tags │ Pack │
├────────────────────────────────┼───────────────────────────┼─────────┼───────────┼──────────────────────────────┼──────┤
│ css-selector-has │ css-has │ Yes │ CSS │ css, popular, bug-prone │ all │
│ css-container-queries │ css-container-queries │ Yes │ CSS │ css, popular │ all │
… (more)
Scanned 128 file(s)
⚠ Found 1 issue(s)
src/components/PriceDisplay.tsx:12:10 RegExp lookbehind may not be supported by your targets. [js-regexp-lookbehind → js-regexp-lookbehind]
↳ Safari: requires ≥ 17.0 (your targets include 16–16.3, 4 versions)
iOS Safari: requires ≥ 17.0 (your targets include 16–16.3, 4 versions)
- “Unknown feature” in an issue: update
web-features
or verify thefeatureId
in your rule. - Expecting an issue but not seeing it? Ensure your
targets
include the affected versions you want to test. - Performance: the scanner ignores
node_modules
,dist
,build
by default. - False positives: rules use regex heuristics—override or refine with inline rules.
MIT © codewithshinde