Teardown

impeccable detect catches real contrast bugs. It passed a Pay button that does nothing

We ran impeccable's detect CLI, trending on GitHub this week, on five live pages and two planted ones. It is fast and deterministic, and it never clicks.

Published Updated 5 min read

impeccable's detect command is worth a place in CI, for about half of what it reports. On our own homepage it found four text colours that fail WCAG contrast and five labels set below a readable size, all real, in eight seconds and with the same answer twice. The other half of its findings are taste rules, which make a poor merge gate. And a clean exit means less than it looks: a checkout page whose Pay button is wired to nothing scanned with zero findings and exit code 0.

impeccable is #4 on GitHub Trending today, with a fresh engine release on 23 October. The detect command is the part that runs without a model. The docs describe it as scanning for "known design problems without starting an AI conversation": contrast, overflowing text, "common AI design patterns", and drift from a design system. Its author has been pointing people at it since July:

What we ran

impeccable 4.7.0 via npx impeccable@latest detect --json, on macOS arm64 with Node 22. Targets:

  1. Five live pages on this site: the homepage, a blog post, /alternatives, /signal, and the homepage again at a 390×844 mobile viewport.
  2. Two local pages we wrote to probe the edges. One is deliberately "AI-styled": a purple-to-violet gradient, gradient heading text, glassy nested cards, emoji labels, 10px text and the word "Supercharge". The other is a plain, well-typeset checkout whose Pay button has an empty onclick.
TargetFindingsOf which advisoryExitTime
Homepage, desktop31728.2 s
Homepage, desktop, second run31, identical72
Homepage, 390×84434102
Blog post6425.7 s
/alternatives30210.9 s
/signal2124.8 s
Planted "AI-styled" page802
Planted dead-button checkout000

What it got right

Contrast, measured, with the colours named. Four homepage findings were real WCAG 1.4.3 failures. Our status red #ff5470 sat on an off-white card at 2.8:1, a green label measured 3.4:1 on white, and the brand orange #e8652d measured 3.0:1 on a light panel. WCAG asks for 4.5:1 for body-size text. We had a rule for exactly this case, a darker orange for light surfaces, and one component still missed it. A human review had not caught it. The linter did, with a CSS selector pointing at the element.

Text that is too small to use. Five findings flagged 10px and 11px text, most of it labels inside a diagram. That is a judgement call on a diagram, but the measurement is correct, and on a phone it is the right flag.

Deterministic. Two desktop runs of the homepage returned the same 31 findings. That makes it usable as a gate: a new finding in a pull request is a real change, not noise.

The "AI look" rules work on the AI look. The planted page got eight findings: gradient text twice, an "AI color palette", low contrast three times, an overused font and a marketing buzzword. It did not flag the card nested inside a card on that page, though it flagged three on our homepage.

What it flags that is taste

Fourteen of the homepage's 24 non-advisory findings are style opinions rather than defects:

  • Nine: a small label above a section heading ("kicker above heading").
  • Three: cards inside cards.
  • One: a marquee of logos.
  • One: that 81% of the text is set in a single typeface.

Each of those is a defensible design note. Not one of them breaks the page for a user. If you run detect as a required check, you will either redesign to its taste or start writing ignore comments, and the second path ends with nobody reading the output. Its own --scope flag helps, but the cleaner split is by rule: gate on contrast, size, overflow and line length, and read the rest as review comments.

What it cannot see

The dead-button checkout is the sharp result. It is a tidy page: one serif font, black text on white, a clear button. Its Pay handler is empty, and its script fires a charge request on page load. detect returned no findings and exit code 0.

That is not a bug in impeccable. It looks at the rendered page and its styles, and it never clicks anything. Its docs are careful about this: "A clean scan means these checks found no reportable problem". The risk is the shortcut a team takes when the check goes green in CI. An agent that builds a page, runs detect and sees exit 0 has proved the page looks deliberate. Whether Pay charges the card once is a different question, and nothing in a static scan answers it.

Verdict

Install it, and gate on its measurable rules. Real contrast failures on a production page, found in seconds and the same twice, are worth the npx. Keep the taste rules advisory. Do not let exit 0 stand in for "the UI works": pair it with a check that drives the flow and reads what happened, because the most expensive bug on our test pages passed with the cleanest score.

Sources

  1. 01GitHub: pbakaus/impeccable (README)github.com
  2. 02GitHub: impeccable engine-v0.1.17 releasegithub.com
  3. 03impeccable docs: the detectorimpeccable.style
  4. 04W3C: Understanding WCAG 2.2 Success Criterion 1.4.3, Contrast (Minimum)www.w3.org
Reticleverdict

// The agent clicked "Pay". Did the right things actually happen?

{verified: "no"failureReason: "POST /api/order returned 500, expected 200"source: "src/checkout/PayButton.tsx:42"}

Example from the README

Your agent says it works. Reticle checks the network, state and console inside your running app, and names the line to fix.

85 of 88 seeded bugs caught in the public benchmark