Alice Monroe
Product designer. Coffee powered. Ship small, ship often. Based in Lisbon.
polish_ audits real UI code for usability, design craft, and accessibility with a self‑hosted Node script, your own API key, no bots in your repo, and no quotas.
The same card, reviewed by the same rubric. The before version is a realistic AI-generated component:
inline hex colors, a clickable <div>, a delete action with no confirmation.
Fix each finding and the score follows. The verdicts below are live model runs on Groq with the default
model, llama-3.3-70b-versatile. Scores shift with the model, so run polish on your own code.
Then polish --verify findings.json re-checks each finding against the updated code,
at a fraction of the cost of a full re-review. Live verdicts vary between models and runs,
so treat any single score as a signal, not a grade.
Two real components, each reviewed by the same rubric. Toggle Before and After to see what polish changes, then flip to Code to inspect the source behind each version.
Product designer. Coffee powered. Ship small, ship often. Based in Lisbon.
Gradient background, hardcoded hex, divs as buttons, no focus styles, cramped 6px gaps.
Live review: 62/100, 3 serious, 2 moderate
Product designer. Coffee powered. Ship small, ship often. Based in Lisbon.
Tokens, real buttons, focus-visible rings, 4px spacing scale, accessible names.
Live review: 78/100, 1 serious, 3 moderate
Divs as labels, no <form>, div-as-submit, no validation, no loading state, hardcoded hex.
Live review: 43/100, 1 critical, 2 serious, 3 moderate
Proper <label> associations, <form> semantics, focus-visible, helper text, loading state, token-based styles.
Live review: 66/100, 0 critical, 1 serious, 6 moderate
The whole pipeline in one terminal: config, prompts, the model call, scoring, and findings with fixes. Recorded from live runs against both demo components with the default model on Groq.
Recorded live run, Groq with llama-3.3-70b-versatile. The same command runs live any time:
polish demo/ProfileCard.before.jsx.
Three layers cover what senior designers check in code. Not screenshots, not vibes. Every rule is written so a model can verify it against source, and the whole thing is plain data, so you can replace it with your own design philosophy.
How the system communicates and recovers: feedback, control, consistency, error prevention, and efficiency. Ten heuristics, H1 to H10.
Design-system discipline and production polish: tokens, type, spacing, motion, components, and the words on the buttons. Seven categories, C1 to C7.
Checkable requirements: contrast, keyboard support, semantics, forms, touch targets, and reduced motion. One pass, A11Y.
Start at 100. Each finding deducts by severity, and criticals cap the ceiling. A score of 60 or above always means zero critical issues. Try it below.
| Severity | Deduction | Example |
|---|---|---|
| critical | 25 | Unreachable by keyboard |
| serious | 10 | Hardcoded hex, no confirmation |
| moderate | 4 | Magic radius, transition: all |
0 criticals score as deducted
1 critical ceiling 59
2 criticals ceiling 49
3 or more ceiling 39
The score never drops below 0.
Works with Groq, OpenAI, Anthropic, Gemini, OpenRouter, or any OpenAI-compatible endpoint. One provider per run, or set a fallback chain and polish tries them in order. Best for app UI reviews. Not a general code quality or backend linter.
# bash
git clone https://github.com/tomiabe/polish.git
cd polish
npm link
# export one key export GROQ_API_KEY=... # or OPENAI / ANTHROPIC / GEMINI / OPENROUTER
polish # audit files matched by config globs polish src/components src/pages/*.tsx # or specific files polish --verify findings.json # re-check that fixes landed polish --json # machine-readable, for CI polish --dry-run # preview cost, no API call
Exits with code 1 when critical findings exist. Wire it into pre-commit or CI.
// .polish.json, everything optional { "provider": "anthropic", "providers": ["gemini", "groq"], "rubric": ["usability", "craft", "accessibility"], "include": ["src/**/*.{tsx,css}"], "maxFiles": 20 }
polish audits this page too. Running polish --dry-run docs/index.html estimates about 29,000 tokens, under a cent on most models.
polish also runs as an MCP server over stdio. Coding agents call the exact same engine as the CLI: identical prompts, identical scoring. Terminal users and AI agents can never disagree.
Review UI files by content. Returns score, counts, assessment, and findings with severity, category, file:line, and a fix.
Re-check previous findings against updated content. Reports FIXED or STILL PRESENT per finding.
Usage status: always unlimited. Self-hosted means no quota and no subscription, just your own key.