pixelpact

Visual contracts for the browser

Your coding agent cannot see
the page it just built.

pixelpact reads the reference page and writes down what it actually renders: sizes, colors, spacing, typography, hover and focus states, animation keyframes, design tokens. That file is the contract. Point pixelpact at your implementation and it answers with one line per property that drifted.

$ npx pixelpact extract https://reference.example.com -o contract.json
$ npx pixelpact check contract.json http://localhost:3000
  • MIT licensed
  • Node 22.12+
  • Chromium via Playwright
  • No account, no service

A coding agent writes the CSS and says it is done. It never sees the result. Nothing hands it a number, so the loop cannot close: the agent guesses, you open the page, you send it back, it guesses again. Every round costs you the one thing the agent was supposed to save.

Three steps, one loop

1

Extract the contract

Point it at the page you are building toward. Nothing has to be approved first.

npx pixelpact extract \
  https://reference.example.com \
  --selector "main" \
  -o contract.json
2

Measure your page

Every value in the contract is asserted against your implementation.

npx pixelpact check \
  contract.json \
  http://localhost:3000 \
  --viewport desktop
3

Fix and run it again

Exit code 0 inside tolerance, 1 outside it. It drops straight into CI.

npx pixelpact side \
  https://reference.example.com \
  http://localhost:3000 \
  --widths 1440,390

What a check prints

A real run against two copies of one page with four declarations changed.

pixelpact check  FAILED
  target    http://localhost:4173/impl.html
  reference http://localhost:4173/ref.html
  viewport  desktop 1440x900
  elements  14 matched, 0 missing of 14
  checks    1056 passed, 10 failed (99.1% of 1066)

deviations (10)
SELECTOR          PROPERTY                  EXPECTED                ACTUAL                  DIFF
body > main > h1  font-size                 48px                    44px                    4px
body > main > a   box.width                 117.75px                109.75px                8px
body > main > a   padding-right             24px                    20px                    4px
body > main > a   padding-left              24px                    20px                    4px
body > main > a   background-color          rgb(11, 114, 133)       rgb(37, 99, 235)        60.1 (color)
body > main > a   border-top-left-radius    8px                     4px                     4px
body > main > a   border-top-right-radius   8px                     4px                     4px
body > main > a   border-bottom-left-ra...  8px                     4px                     4px
body > main > a   border-bottom-right-r...  8px                     4px                     4px
body > main > a   focus.outline             rgb(11, 114, 133) s...  rgb(37, 99, 235) so...  differs

Run the same check against the reference itself and all 1066 assertions pass, which is the property that matters: a passing check has to mean something. Add --json to get the same report as a data structure, which is what CI jobs and agents read.

Side by side, differences boxed

check says which values moved. diff says how many pixels moved. side splits both pages into sections and shows you where to look.

One section of a reference page and an implementation compared next to each other, the differences boxed in red
#   SECTION   WIDTH   VERDICT  DIFF
01  hero      1440px  PASS     0.000%
02  features  1440px  FAIL     0.675%
03  pricing   1440px  PASS     0.000%
04  foot      1440px  FAIL     1.265%

For coding agents

An agent that writes UI code cannot tell whether it succeeded. pixelpact-mcp gives it the measurement, so the loop closes without a person in the middle: extract the contract once, then let the agent check its own work, read the deviation list, fix, and check again.

Tools exposed: extract_contract, check_implementation, diff_pixels, read_contract_summary

// .mcp.json
{
  "mcpServers": {
    "pixelpact": {
      "command": "npx",
      "args": ["-y", "pixelpact-mcp"]
    }
  }
}

Why this is not visual regression testing

Percy, Chromatic, Applitools and BackstopJS compare your page against a baseline you approved earlier. While you are still building toward a design, there is no baseline.

ComparisonVisual regression toolspixelpact
Compares againsta snapshot you approved earlierthe reference design itself
Useful whenthe UI is already correctthe UI is being built
First run on a new pagerecords, cannot judgemeasures against the reference
Answer you getan image diff to inspect by eyea value per property, with a delta
Fits an autonomous agentneeds a human to approve the diffthe numbers close the loop

The two models are complementary. Use a regression tool to keep a finished page finished, and pixelpact to get it finished in the first place.

What it measures

Contract from the reference

Reads the page you are building toward and writes down every value it renders. Nothing to approve first.

Numbers, not opinions

Each deviation carries the expected value, the measured value and the difference between them.

States, not just layout

Interactive elements are hovered and focused, and only the properties that actually change are stored.

Tokens and keyframes

Custom properties on the root element and named animation keyframes travel inside the contract.

Pixel comparison

When every value passes and it still looks wrong, compare the screenshots and get a percentage.

Plain JSON

The contract is a file you can read, diff and review in a pull request. No service, nothing to log into.

Pull request checks

A composite Action runs the check and keeps one comment on the pull request up to date.

Framework agnostic

It measures the rendered DOM, so React, Vue, Svelte and hand written HTML are all the same to it.

Figma as reference

A Figma url is read through the REST API, and the contract binds to your markup by data-contract.

Four commands

CommandWhat it does
pixelpact extract <url>Reads the reference and writes a contract file
pixelpact check <contract> <url>Measures an implementation, prints deviations, sets exit code
pixelpact diff <contract> <url>Pixel comparison against the screenshot stored in the contract
pixelpact side <reference> <url>Section by section images with the differences boxed

Install

$ pnpm add -D pixelpact playwright
$ pnpm exec playwright install chromium

playwright is a peer dependency, so the browser download stays under your control and a project that already has Playwright installs nothing extra.