{"slug": "why-npm-run-build-is-not-qa-for-ai-generated-frontend-code-8-browser-traps-and", "title": "Why \"npm run build\" is not QA for AI-generated frontend code (8 browser traps and 72 UI craft rules)", "summary": "A developer released three MIT-licensed open-source tools aimed at catching frontend failures that AI coding agents miss because they only verify that `npm run build` passes. ghost-qa runs headless Playwright Chromium against a local dev server, crawling internal routes at three viewports in light and dark schemes and scoring results across eight \"traps\" with selector-level reports and a patch prompt agents can act on, while unslop audits 72 UI craft rules across seven pillars and emits a 0-100 score plus a refactor plan that swaps generic defaults like purple-to-indigo gradients and arbitrary spacing for design tokens. Both tools ship as MCP servers so agents such as Claude Code, Cursor and Cline can call them directly, and the developer notes the limits: ghost-qa targets localhost dev servers and is not a full WCAG audit, and unslop is static analysis encoding the author's own taste rules.", "body_md": "AI coding agents are very good at making `npm run build` go green. They are much worse at noticing that the page they just built is broken in a real browser, or that it looks like every other AI-generated page on the internet.\n\nI build and maintain three small open-source tools for this problem, so a disclosure first: everything below is about my own projects, and I wrote this with AI assistance. All three are MIT licensed and free.\n\n`tsc` and `npm run build` answer one question: does this code compile and bundle? They say nothing about what happens when a browser runs it. In my experience, agent-written frontends fail in two ways that a compiler cannot see.\n\n**1. Runtime browser regressions.**\n\n`500` while the UI renders an empty state, so nothing looks \"broken\" in the code.\n**2. Generic \"AI slop\" defaults.**\n\nPurple to indigo gradients, three centered feature cards, cards nested inside cards, arbitrary spacing values that break the scale, hardcoded colors instead of tokens, and marketing copy like \"Unleash the power\". None of it is a bug. All of it makes the product look interchangeable.\n\nThe agent says \"done\" because the only check it ran was the build. So I wanted to give it two more checks that it can run itself, plus a third one for security.\n\n[ghost-qa](https://github.com/avivgerz-hue/ghost-qa) launches headless Playwright Chromium against your running dev server, crawls the internal routes, and records what actually happened. It checks every page at three viewports (Desktop 1440x900, Tablet 768x1024, Mobile 375x812) in both light and dark color schemes.\n\n```\nnpm run dev\nnpx playwright install chromium   # one-time\nnpx -y ghost-qa@latest test http://localhost:3000\n```\n\nThe engine is organized as eight traps, each one watching a different failure class:\n\nEach trap starts at 100 and loses points per finding, and the overall result is a QA Health Score with a letter grade. The part that matters for agents is the output: a structured report with exact selectors and bounding boxes, plus a patch prompt the agent can act on. `ghost-qa compare before.json after.json` then diffs two runs, so the agent can prove a fix worked without introducing regressions.\n\nIt also runs as an MCP server, so Claude Code, Cursor or Cline can call it as a tool instead of shelling out.\n\nSome limits, because I would rather you know them: it is meant for localhost dev servers, its interaction runner only clicks ordinary controls and refuses destructive-looking ones (that is a word list, not magic), it is not a full WCAG audit, and it does not replace your own test suite.\n\nThe second failure mode is harder to test, because \"looks generic\" is a taste problem. [unslop](https://github.com/avivgerz-hue/unslop) takes the position that a lot of that taste can be written down as rules and checked deterministically.\n\n```\nnpx -y unslop-mcp audit .\nnpx -y unslop-mcp refactor-plan . --report UNSLOP-REPORT.md\n```\n\nIt audits 72 rules across seven pillars: color and contrast, typography, layout and spatial rhythm, surface and elevation, copy, interaction and motion, and theme and token architecture. Every finding has a file:line:column location, and the result is a 0 to 100 craft score with a per-pillar scorecard. You can gate CI or an agent loop with `--fail-under 95`.\n\nThe refactor plan turns findings into concrete replacements, for example `from-purple-500 via-pink-500 to-indigo-500` into a surface token, `p-[13px]` into a spacing token, and `transition-all` into `transition-colors motion-reduce:transition-none`.\n\nIt also installs one of ten built-in design archetypes (or extracts design DNA from CSS or a URL) and exports the tokens as a Tailwind v4 `@theme` block, a Tailwind v3 config fragment, plain CSS custom properties, or W3C design tokens JSON, so the agent builds on a token contract instead of inventing colors per component.\n\nThe honest limit: this is static analysis. It checks the source, not the rendered page, and the rules encode my own opinions about craft. A good score is not a good design, which is why the two tools are meant to be used together.\n\nThe third tool covers the part neither of the above looks at. [vibe-shield](https://github.com/avivgerz-hue/vibe-shield) is a static security scanner for AI-written code: server secrets behind `NEXT_PUBLIC_` variables, mutation routes without a session check, IDOR shapes, tables without row level security, and poisoned MCP or skill configuration.\n\n```\nnpx -y @vibefoundry/vibe-shield@latest scan .\n```\n\nIt is heuristic, so a clean score is not a security guarantee, but it catches the exact shapes agents tend to produce.\n\nThe loop I use with an agent is simple: after it writes a feature, it runs the static checks (`unslop audit`, `vibe-shield scan`), starts the dev server, runs `ghost-qa test`, fixes what comes back, and only then reports completion. Each tool exits non-zero on blocking findings, so \"done\" becomes an exit code instead of an opinion. `init` for each tool installs the instructions and MCP config for Claude Code, Cursor, Codex, Windsurf, Copilot, Cline and Zed.\n\n**Autonomous headless browser QA & self-healing verification loop for coding agents.** `v2.1.1` — the 8-Trap Deep Browser Inspection Engine: 3 viewports × light/dark, QA Health Score (A+…F), interactive HTML dashboard, and regression diffing.\n\n⭐ **If this tool helps your AI coding workflow, please give this repository a Star!** It helps more developers discover the project.\n\n*One command each — star all three and keep the whole suite free & maintained:*\n\n`npx -y unslop-mcp@latest init`)` npx -y @vibefoundry/vibe-shield@latest scan .`)` npx -y ghost-qa@latest test http://localhost:3000`)\n\n```\nnpx -y ghost-qa@latest test http://localhost:3000\n```\n\nCoding agents (Claude Code, Codex, Cursor, Windsurf) write code **blind** — then declare victory while the actual browser has React hydration errors, broken buttons…\n\n**VibeFoundry Agent Suite:** 🎨 **[unslop](https://github.com/avivgerz-hue/unslop)** — UI Design DNA & Anti-Slop Engine (`npx -y unslop-mcp@latest init`) · 🛡️ **[vibe-shield](https://github.com/avivgerz-hue/vibe-shield)** — Security Scanner for AI Code (`npx -y @vibefoundry/vibe-shield@latest scan .`) · 👻 **[ghost-qa](https://github.com/avivgerz-hue/ghost-qa)** — Autonomous Headless Browser QA (`npx -y ghost-qa@latest test http://localhost:3000`)\n\n```\nnpx -y unslop-mcp@latest init\n```\n\n**Your agent can write the code. unslop gives it a measurable design engineering protocol.**\n\n`unslop` is a zero-runtime-dependency **UI/UX Design Engineering CLI, native MCP Server, and AI Agent Skill**. It audits 72 rules across seven design craft pillars, installs ten studio-grade archetypes, extracts Design DNA, exports four token formats, and turns every finding into an exact, prioritized transformation blueprint for JSX/TSX, HTML, Vue, Svelte, CSS, and Tailwind codebases.\n\nWorks natively with **Claude**…\n\n**The security gate for AI-written code.** Find exposed secrets, unguarded routes and missing RLS before you ship.\n\n```\nnpx -y @vibefoundry/vibe-shield@latest scan .\n```\n\nIllustrative two-file scan; fixes are applied manually. Results vary by project. A clean score is not a security guarantee.\n\nvibe-shield is a **static security scanner** plus an **Agent Skill** that helps Claude Code, Codex, Cursor and Windsurf audit before they say *“done”*.\n\nThe v2 catalogue covers client exposure; auth and route protection; database/RLS; AI and…\n\nIf you try any of them on a real project, I would especially like to hear about false positives. Those are the most useful bug reports I can get.", "url": "https://wpnews.pro/news/why-npm-run-build-is-not-qa-for-ai-generated-frontend-code-8-browser-traps-and", "canonical_source": "https://dev.to/avivgerzhue/why-npm-run-build-is-not-qa-for-ai-generated-frontend-code-8-browser-traps-and-72-ui-craft-rules-5dii", "published_at": "2026-11-12 15:50:19+00:00", "updated_at": "2026-11-12 15:52:03.449434+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-products"], "entities": ["ghost-qa", "unslop", "Playwright", "Claude Code", "Cursor", "Cline", "Tailwind"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/why-npm-run-build-is-not-qa-for-ai-generated-frontend-code-8-browser-traps-and", "markdown": "https://wpnews.pro/news/why-npm-run-build-is-not-qa-for-ai-generated-frontend-code-8-browser-traps-and.md", "text": "https://wpnews.pro/news/why-npm-run-build-is-not-qa-for-ai-generated-frontend-code-8-browser-traps-and.txt", "jsonld": "https://wpnews.pro/news/why-npm-run-build-is-not-qa-for-ai-generated-frontend-code-8-browser-traps-and.jsonld"}}