AI-powered frontend visual regression testing for web teams β detect, understand, and fix visual bugs before they ship to production.
Backend has Datadog, Sentry, PagerDuty β a $20B+ monitoring ecosystem. Frontend gets... manual QA and hoping for the best. Frontguard changes that.
44 test files Β· multi-browser Β· AI vision analysis Β· self-hostable Β· MIT
Numbers above are derived from source by
scripts/stats.ts(regenerated on everynpm run stats). Seescripts/stats.jsonfor the canonical snapshot.

π½οΈ Demo: frontguard init β doctor β run β AI classification.
Five packages just shipped to npm:
@frontguard/cli,@frontguard/playwright,@frontguard/mcp,@frontguard/netlify-plugin,create-frontguard-plugin. Full release notes in CHANGELOG.md; go/no-go indocs/launch-readiness.md; first validation run results invalidation/results-v0.2.md(0.0% pixel-only false positives on 43 recheck routes).
Every line of Frontguard is MIT-licensed and lives in this repo. The CLI, the AI vision pipeline, the cloud-api (Cloudflare Workers + D1 + R2), the four integrations (Slack / GitHub / Vercel / Netlify), the MCP server, the Dockerised cross-OS renderer, and the self-host docker-compose are all here. The 21 PRs that built v0.2.0 are all on main β you can read the adversarial review we audited the prior state against, the competitive research that anchored the boundary, and the product-completion plan that defined what "complete" meant. Nothing is hidden behind a "request a demo."
If you'd rather not run your own AI keys, the cloud is opt-in. If you'd rather not use the cloud, the CLI is free forever. If you'd rather run the whole stack on your own machines, the self-host guide is the recipe.
- π§ AI-powered analysis β Doesn't just say "pixels differ." It classifies the change (regression vs intentional vs content update), explains why, and suggests a fix. This kills the #1 pain of visual testing: false positives.
- π― Anti-flake rendering β Multi-render consensus eliminates the flaky-screenshot noise that makes teams disable their visual suites.
- π€ In-IDE agents via MCP β
@frontguard/mcpexposes "what regressed on this PR" and "give me the suggested fix for diff N" to Claude Code / Cursor / Copilot. - π³ Cross-OS byte-equivalent baselines β pinned Docker renderer so a fix that closes the diff on macOS closes it on Linux CI too. No more 428-day flake debugging.
- π Open-source & self-hostable β CLI-first, free forever. No per-screenshot pricing cliff, no dashboard lock-in, BYO AI key. The self-host guide is a one-command recipe.
Developer pushes code β Frontguard renders every page β Compares to baselines β
AI explains what changed and why β Suggests fixes β Posts PR comment
- Detect β Pixel diff + DOM diff catches what humans miss
- Understand β AI explains why something broke, not just "pixels differ"
- Fix β Verified code fixes, re-rendered to confirm they work (Phase 2)
Prerequisites: Node.js 20+ and npm 9+
# Install
npm install @frontguard/cli
# Initialize config (auto-detects your framework, --ci adds a GitHub Action)
npx -p @frontguard/cli frontguard init --ci
# Verify your environment is ready
npx -p @frontguard/cli frontguard doctor
# Run visual regression tests
npx -p @frontguard/cli frontguard run --url http://localhost:3000
# Accept current screenshots as new baselines
npx -p @frontguard/cli frontguard update-baselinesFull documentation: frontguard.dev/docs Β· internal notes in
docs/
- Zero-config route discovery β Auto-crawls your app to find all pages
- Multi-browser β Chromium, Firefox, WebKit via Playwright
- AI-powered analysis β BYOK (OpenAI/Anthropic) classifies regressions vs intentional changes
- Smart rendering β Dependency graph renders only pages affected by your changes
- Preview deployments β Auto-detects Vercel/Netlify preview URLs
- Git-native baselines β Stored in orphan branch, zero main branch bloat
- Framework detection β Next.js, Remix, SvelteKit, Nuxt, Astro out of the box
- Security hardened β Shell injection prevention, path traversal guards, API key redaction
- Memory managed β Streaming buffers, temp file cleanup, bounded concurrency
- PR thumbnails β Baseline/current/diff images embedded in PR comments (R2/S3/GitHub artifacts)
- Per-route thresholds β Strict on
/checkout, relaxed on/blogβ all in one config
| Frontguard | Percy | Chromatic | BackstopJS | Lost Pixel | Argos | |
|---|---|---|---|---|---|---|
| Open source | β MIT | β | β | β | β (read-only) | β MIT |
| CLI-first | β | β | β | β | β | β |
| AI change classification | β | β | β | β | β | β |
| AI fix verification | β | β | β | β | β | β |
| Anti-flake rendering | β | β | β | β | β | β |
| Self-hostable | β | β | β | β | β | π‘ |
| Free tier | Forever (CLI) | Trial β $399/mo | Storybook hobby | Free | Sunset | Hobby + unlimited Playwright traces |
| Pro entry | $29/mo (optional) | ~$399/mo | $179/mo | n/a | n/a | $100/mo |
| Actively maintained | β | β | β | β (low activity) | β (Figma acqui-hire 2026-04-22) | β |
Migrating? See the BackstopJS, Lost Pixel, and Argos guides. Comparisons: Percy Β· Chromatic Β· Argos.
β /dashboard @ 375px β 2.34% changed
π΄ AI Analysis β Regression (94% confidence)
"The sidebar overlaps the main content on mobile. A flex-direction
change in Dashboard.module.css:28 removed the column stacking."
Suggested fix: restore `flex-direction: column` at the < 768px breakpoint.
β /pricing @ 1440px β 0.8% changed
π’ AI Analysis β Intentional (91% confidence)
"New 'Enterprise' pricing tier added. Layout intact, content expanded."
// frontguard.config.ts
export default {
version: 1,
baseUrl: 'http://localhost:3000',
// Auto-discover routes (zero config)
discover: {
startUrl: '/',
maxDepth: 3,
exclude: ['/admin/*', '/api/*'],
},
// Or explicit routes
// routes: ['/', '/pricing', '/checkout'],
viewports: [375, 768, 1440],
browsers: ['chromium'],
threshold: 0.1,
// AI analysis (optional, BYOK)
ai: {
provider: 'openai',
model: 'gpt-4o',
},
// Ignore dynamic content
ignore: [
{ selector: '.dynamic-timestamp' },
],
};βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β ROUTE DISCOVERY βββββΆβ RENDER PAGES βββββΆβ PIXEL DIFF β
β Crawl / Config β β Playwright Γ β β pixelmatch β
β / Filesystem β β viewports Γ β β fast gate β
β β β browsers β β (90% pass here)β
βββββββββββββββββββ ββββββββββββββββββββ ββββββββββ¬βββββββββ
β changed
βΌ
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
β PR COMMENT ββββββ AI ANALYSIS ββββββ DOM DIFF β
β Visual diffs β β GPT-4V / Claude β β Structural + β
β Explanation β β Classify + β β computed styles β
β Fix suggestion β β explain + fix β β β
βββββββββββββββββββ ββββββββββββββββββββ βββββββββββββββββββ
frontguard
π Discovering routes... found 47 routes
π 12/47 routes affected by changed files
π₯ Rendering 12 routes Γ 3 viewports
βββββββββββββββββββββββββββββββββββββββββββ
RESULTS 12 routes
βββββββββββββββββββββββββββββββββββββββββββ
β / 375 768 1440 PASS
β /pricing 375 768 1440 PASS
β /checkout 375 768 1440 WARNING
β /dashboard 375 768 1440 REGRESSION
β
/settings 375 768 1440 NEW
βββββββββββββββββββββββββββββββββββββββββββ
β /dashboard @ 375px
AI: "Sidebar overlaps main content on mobile.
flex-direction change in Dashboard.module.css:28"
Severity: π΄ Critical (confidence: 94%)
1 regression Β· 1 warning Β· 9 passed Β· 1 new
Frontguard ships with a plugin architecture (6 lifecycle hooks) and 5 built-in plugins:
| Plugin | Description | Key Features |
|---|---|---|
Figma (src/plugins/figma.ts) |
Design-to-code comparison | Figma API integration, design token extraction, component mapping |
Performance Budgets (src/plugins/perf-budgets.ts) |
Web Vitals & budgets | LCP/CLS/TTFB thresholds, violations correlated with the visual diff |
Accessibility (src/plugins/accessibility.ts) |
axe-core audits | WCAG checks (contrast, alt text, target size, focus, headings) in the same render pass |
Third-Party Scripts (src/plugins/third-party-scripts.ts) |
Script drift detection | Flags ad/analytics/widget origins that appear or disappear between runs |
Monitor (src/plugins/monitor.ts) |
Production visual monitoring (CLI + optional cloud scheduler) | Live-URL checks, threshold alerting, history tracking |
Plugin lifecycle hooks: beforeDiscover, afterDiscover, afterRender, afterCompare, afterRun, onError
// frontguard.config.ts
import { createFigmaPlugin } from '@frontguard/cli/plugins';
export default {
// ...base config
plugins: [
createFigmaPlugin({ fileKey: 'your-figma-file-key' }),
],
};src/
βββ cli/ # CLI entry point (Commander.js)
βββ core/ # Pipeline orchestrator, types, config, plugin system
βββ discovery/ # Route discovery (crawler + filesystem)
βββ render/ # Playwright rendering engine
βββ diff/ # Pixel diff + AI vision analysis
βββ storage/ # Git orphan branch baselines
βββ report/ # Console, JSON, HTML, GitHub PR reporters
βββ plugins/ # Figma, perf budgets, accessibility, third-party scripts, monitoring
βββ utils/ # Redaction, logging, retry
Pipeline: discover β filter β render β diff β analyze β report
Each stage is independent with error boundaries β one page failing doesn't kill the run.
See docs/ for:
- Product deep-dive β Architecture decisions and design rationale
- Launch readiness (v0.2.0) β Go/no-go for the 2026-06-17 release, 20-PR punch list, residual risks
- Adversarial review β The audit we held v0.2.0 to
- Product-completion plan β The frozen IN / ROADMAP / FIX boundary
- Research β Mid-2026 competitive landscape (16 competitors fetched live)
- Validation results β Real harness run, real numbers
See ROADMAP.md for the full milestone history and upcoming plans.
The release flow is documented and reproducible β no hidden steps.
- Tag a version:
git tag -a v0.X.Y -m "..."andgit push origin v0.X.Y. .github/workflows/release.ymlruns on the tag push:scripts/release.sh --dry-runfirst as a sanity check, then real publish withNPM_TOKENfrom repo secrets (provenance signing in CI). Marketplace submissions emit as a workflow summary.scripts/release.shis the single source of truth. Run it locally with--dry-runfor any audit βnpm pack --dry-runper package, manifest checks, no state mutated.
Idempotent: already-published versions are skipped automatically. Scoped packages are forced public after publish so org defaults can't silently restrict them.
# AI Analysis (optional, BYOK β bring your own key, pick one)
FRONTGUARD_OPENAI_KEY=sk-...
FRONTGUARD_ANTHROPIC_KEY=...
# GitHub PR comments
GITHUB_TOKEN=ghp_...Note: AI keys are optional. Frontguard works without them β pixel diff and DOM diff run locally. AI analysis (classification, explanations, fix suggestions) activates only when a key is provided.
Contributions welcome! See CONTRIBUTING.md for guidelines, development setup, and how to submit PRs.
MIT