squint

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.

  1. The page is blankruntime probe
  2. The build brokedev-server sweep
  3. An error in the consoleruntime probe
  4. A font file that 404sruntime probe
  5. A class with no CSS behind itphantom-class check
  6. A text field with no labelaccessibility sweep
  7. A focus ring you can't seekeyboard walk
  8. Body text in pale graycontrast check
  9. Links four pixels aparttarget spacing
  10. An image that shoves the page as it loadsimage check
  11. 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:

  1. Types and lint. Your project's own typecheck and lint scripts. This takes seconds.
  2. The dev server. Once you start it with /dev, squint reads its output for build errors that appeared during the turn.
  3. 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.
  4. 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.

  1. Aa .woff2 404

    The heading's font file does not exist

    Fails the run
    runtime: 1 failed request(s)

    The heading still shows up, in a fallback font, so the page looks fine and the missing file goes unnoticed.

  2. Read the latest issue class="btn btn-primery" a

    A class name is misspelled

    Fails the run
    phantoms: btn-primery (on <button>)

    It should be btn-primary. The button renders with none of its styles, and nothing reports an error.

  3. team.svg

    An image has no alt text

    Advisory
    img missing alt: team.svg

    A screen reader either skips it or reads the file name aloud.

  4. The same image has no width or height

    Advisory
    image: <img team.svg> has no width/height or aspect-ratio — it reserves no space and shifts layout when it loads

    Whatever you were reading jumps down the page when the image arrives.

  5. label? you@example.com

    A text field has no label

    Advisory
    form 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.

  6. Show past issues Tab

    A div is doing a button's job

    Advisory
    clickable <div.more> is not focusable and has no role — unreachable without a mouse

    It works when you click it. It does not exist if you use a keyboard.

  7. Issues Archive About ? Tab

    The focus outline is switched off

    Advisory, three times
    keyboard: focus invisible on <a#nav-issues> (tab stop 1) — outline and box-shadow both none

    The same line appears for the two links after it. squint found this by pressing Tab on the page, not by reading the stylesheet.

  8. Written by two people who would rather show you a Lc 41

    Body text is set in pale gray

    Advisory
    low APCA contrast: Lc 41 on <p> body text ("Written by two people who would rather s…") — fog, not elegance

    The drawing uses the real colors. Lc is a contrast score, and higher is easier to read.

  9. 24px 16px

    Four small links sit four pixels apart

    Advisory, twice
    4 interactive element(s) smaller than 24x24px target spacing: small tap targets sit closer than 24px apart (WCAG 2.5.8) — enlarge them or add spacing

    A 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 /context shows 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. /review helps, 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.