squint checks the page your coding agent just built.
It is a terminal app that sits on top of the agent CLI you already use. After each turn it runs your type checker and linter, reads your dev server's output, opens the page in headless Chrome, and gives the agent a list of what is actually wrong.
npx @aayambansal/squint
Run it inside a frontend repo. It needs Node 22 or newer and one agent CLI. It is free and MIT licensed, with no account and no telemetry.
What a quick look misses
Problems on a web page, in order of how easy they are to see. You would catch the top lines yourself. squint is for the rest.
- The page is blankruntime probe
- The build brokedev-server sweep
- An error in the consoleruntime probe
- A font file that 404sruntime probe
- A class with no CSS behind itphantom-class check
- A text field with no labelaccessibility sweep
- A focus ring you can't seekeyboard walk
- Body text in pale graycontrast check
- Links four pixels aparttarget spacing
- An image that shoves the page as it loadsimage check
- A div pretending to be a buttonaccessibility sweep
Beside each line is the check that catches it. Where the two bars sit is a guess, not a measurement.
What happens on each turn
You type what you want changed. squint adds its design brief and your project's rules to the request, takes a checkpoint of your files, and passes it to your agent. When the agent is done, squint checks the result in this order:
- Types and lint. Your project's own typecheck and lint scripts. This takes seconds.
- The dev server. Once you start it with
/dev, squint reads its output for build errors that appeared during the turn. - The page. If the build is clean, squint loads the page in headless Chrome and looks for exceptions, console errors, failed requests, and the kinds of mistake shown in the next section.
- A screenshot. Compared with the one from the turn before, so you can see how much of the page changed and which element moved.
Anything that fails goes into a list of problems. /fix sends that list to
the agent. If you turn on autoFix, squint sends it for you, twice at most per
request. /undo puts your files back.
It is the prompt, preview and fix loop that Lovable made familiar, run locally against your own repo with the agent you already pay for.
A run you can check
This is a small newsletter page with nine mistakes planted in it. Each one is marked with a comment in its source. Here is what squint 1.0.2, installed from npm, said about it.
$ npx @aayambansal/squint ci --url https://aayambansal.github.io/squint/specimen/ ✗ audit: 2 hard finding(s) runtime: 1 failed request(s) phantoms: btn-primery (on <button>)
Those are the first lines it prints. It then exits with a failure and saves a JSON report holding fourteen findings. The two above fail the run. The other twelve are advisories: reported, not blocking. Below is each planted mistake next to squint's own words for it.
-
The heading's font file does not exist
Fails the runruntime: 1 failed request(s)The heading still shows up, in a fallback font, so the page looks fine and the missing file goes unnoticed.
-
A class name is misspelled
Fails the runphantoms: btn-primery (on <button>)It should be
btn-primary. The button renders with none of its styles, and nothing reports an error. -
An image has no alt text
Advisoryimg missing alt: team.svgA screen reader either skips it or reads the file name aloud.
-
The same image has no width or height
Advisoryimage: <img team.svg> has no width/height or aspect-ratio — it reserves no space and shifts layout when it loadsWhatever you were reading jumps down the page when the image arrives.
-
A text field has no label
Advisoryform control without label <input.field>A placeholder is not a label. It is gone as soon as you start typing, and a screen reader may never announce it.
-
A div is doing a button's job
Advisoryclickable <div.more> is not focusable and has no role — unreachable without a mouseIt works when you click it. It does not exist if you use a keyboard.
-
The focus outline is switched off
Advisory, three timeskeyboard: focus invisible on <a#nav-issues> (tab stop 1) — outline and box-shadow both noneThe same line appears for the two links after it. squint found this by pressing Tab on the page, not by reading the stylesheet.
-
Body text is set in pale gray
Advisorylow APCA contrast: Lc 41 on <p> body text ("Written by two people who would rather s…") — fog, not eleganceThe drawing uses the real colors. Lc is a contrast score, and higher is easier to read.
-
Four small links sit four pixels apart
Advisory, twice4 interactive element(s) smaller than 24x24pxtarget spacing: small tap targets sit closer than 24px apart (WCAG 2.5.8) — enlarge them or add spacingA fingertip covers two of them at once.
Two it was not asked about
Nine were planted and nine were found. The report also holds two lines for mistakes that were not put there on purpose. Both are true.
font loading: @font-face "Notes Display" has no font-display and no size-adjust — text flashes invisible then reflows when the webfont loads (add font-display:swap + a metric-adjusted fallback)
meta: no og:image — shared links render as a bare URL with no preview card
There are many more checks than these. The check catalog lists every one and what it catches.
Try it
You need three things.
- Node 22 or newer.
- One agent CLI, installed and signed in. squint drives it and does not replace it. Any of these works: Claude Code, Codex, Gemini CLI, Antigravity, OpenCode, Amp, Cursor CLI, Copilot CLI or Aider. There are setup notes for each.
- Chrome or Chromium for the page checks. On a Mac, Edge and Brave work too.
Then, in your project:
cd your-project npx @aayambansal/squint
Inside squint, type what you want in plain words. These commands cover most of a session:
/dev start your dev server under squint /review screenshots at 390, 768 and 1440 wide, then a critique /problems what the checks found /fix send the problems to the agent /undo put your files back
squint doctor shows which agents and which browser it found on your machine.
To start from an empty folder instead, npx @aayambansal/squint init my-app
scaffolds a Vite, React and Tailwind project.
Built on macOS and tested on Linux in CI. Windows has not been tested.
What it won't do
- It does not write the code. Your agent does, on your account and at your cost.
squint makes each request a little longer by adding its brief and your rules, and
/contextshows how many tokens that adds. - It cannot tell you a page is good. The checks measure what can be measured.
Whether the design is any good is still your call.
/reviewhelps, but it is the agent judging screenshots of its own work. - It will be wrong sometimes. The checks are heuristics. Expect the occasional false alarm, and expect it to miss things.
- It is one person's project. It is at version 1.0.2 and changes often. Some of what the repository describes is on the main branch and not on npm yet.
If something is broken or confusing, open an issue.