Project Story — baseline-check (blc)

Inspiration

baseline-check was born from a common developer pain: shipping features only to discover a browser compatibility surprise later. Many teams want to adopt modern web platform APIs and CSS features, but maintaining a mental map of which features are "baseline" (widely safe) vs. "new" across browsers is hard. I wanted a tiny, fast tool that scans a codebase and answers: which platform features are we using, where do they appear, and are they safe to rely on now?

What it does

baseline-check scans your project's HTML, CSS and JavaScript/TypeScript files and reports which web platform features are used. For each finding it provides:

  • file and line number (when available)
  • mapped feature name and category (from web-features)
  • baseline/adoption status and baseline dates (via compute-baseline)
  • grouping and summary modes
  • a simple Baseline Score to summarize risk
  • JSON output for tooling and integrations

CLI highlights: --all, --new, --warnings/-w, --summary/-s, --json, --group, --since, and --limit.

How we built it

  • File discovery: fast-glob finds **/*.{html,css,js,jsx,ts,tsx} while ignoring node_modules, dist, and .git.
  • CSS parsing: css-tree is used to extract declarations and their exact source positions (line numbers).
  • HTML parsing: parse5 enumerates elements, inline style attributes, and inline <script> content and we compute line numbers from offsets.
  • JS/TS detection: lightweight heuristics scan for dotted identifiers (e.g., navigator.gpu, Array.prototype.at) and constructor-like names (IntersectionObserver) as API candidates.
  • Mapping & enrichment:
    • For CSS/HTML we construct BCD-like keys (e.g., css.properties.grid-template-columns) and query compute-baseline.getStatus().
    • Where direct lookups fail we try fallback keys (parent property keys) or find features that list the compat key in web-features.
    • For JS candidates we heuristically match API names against web-features entries.
  • CLI & UX: index.js formats reports (file-by-file or grouped), computes counts and a Baseline Score, and supports JSON output. bin/blc is a tiny launcher that normalizes args and defaults to show useful output.

Key files: src/scanner.js (scanner/enrichment), index.js (CLI formatting), bin/blc (launcher).

Challenges we ran into

  • Mapping tokens to BCD/feature IDs is tricky. CSS values and HTML attributes don't always map cleanly to a single BCD key, so fallbacks and dataset scans were necessary.
  • JavaScript detection via regexes is brittle. It captures many APIs but can miss deeper member chains or generate false positives.
  • Computing accurate line numbers for HTML required offset arithmetic from parse5 locations; fragments and minified inputs can still produce edge cases.
  • Making the tool robust for large repos without producing noise required careful default filters (ignore node_modules, dist, .git) and limiting output by default.

Accomplishments that we're proud of

  • A working, developer-friendly CLI that delivers line-precise feature findings.
  • Integration with authoritative datasets (web-features, compute-baseline) to provide meaningful baseline dates and statuses.
  • Flexible output modes (file/group/JSON/summary) that make the tool useful for both humans and automation.
  • Lightweight approach with minimal heavy dependencies yet practical accuracy for many real projects.

What we learned

  • Authoritative feature datasets (like web-features) add real value — they convert raw tokens into actionable signals.
  • AST-based parsing for CSS/HTML is worth it; css-tree and parse5 provide the structure and positions required for developer-facing feedback.
  • Regex heuristics are a fine starting point for JS, but for production-grade accuracy an AST-based approach is needed.
  • Small UX choices (launcher defaults, summary score) significantly affect usefulness and adoption.

What's next for baseline-check

Planned improvements:

  • Replace JS regex heuristics with a lightweight AST parser (e.g., meriyah or esprima) to reliably capture member expressions and reduce false positives.
  • Improve CSS value normalization and mapping to BCD keys to catch more matches.
  • Add unit tests for scanCSS, scanHTML, and JS candidate extraction to prevent regressions.
  • Add CI (GitHub Actions) to run linting and tests automatically and enable release automation.
  • Explore editor integrations (language server / VS Code extension) for inline diagnostics and quick MDN links for non-baseline features.

Built With

Share this project:

Updates