Skip to main content

See every pixel your PR changed

A GitHub Action that posts pixel diffs of production against your preview deploy on every pull request.

Production

The page as it is today.

Preview

The page as this change ships it.

No screenshots at hand? Use a real pair.

Try a real example

Every PR gets a visual diff

Code review shows you the lines that changed. difftool shows you the page they changed, next to the one your users see today.

  1. Waits for your preview

    With head set to vercel, the action polls the deployment for the PR's head commit and starts the moment it is ready. Any other host works with a plain URL.

  2. Screenshots both deploys

    Microlink renders every route you list as a full-page screenshot, once on production and once on the preview, with the same browser and viewport.

  3. Compares them pixel by pixel

    Each pair is diffed and scored against your threshold: under it passes, a little over warns, far over fails the check.

  4. Comments once, keeps it fresh

    One sticky comment on the pull request, rewritten on every push. When the PR closes, its screenshots are deleted from your bucket.

github-actions commented on #192

@microlink/difftool visual comparison

base unavatar.io · head unavatar-5xos75mnn-microlink.vercel.app

1/2 routes with warnings

RouteChangesCompareVerdict
/3.52%compareWarning
/styleguide0.17%comparePass
The sticky comment difftool posts on a pull request
The unavatar.io hero in highlight mode: the badge changed from “The open source avatar API” to “Star us on GitHub”, the headline from “The universal avatars API” to “One URL for every avatar”, and the pixels that changed past the highlight threshold are painted pink.
Where the 3.52% starts: a new badge and headline, with every pixel past the highlight threshold painted pink. Each run also renders a full review image with production, preview and diff side by side.

Five ways to read a change

Every compare link in the comment opens here. This is the pull request from above: a new badge, headline and intro on unavatar.io, and everything under them moved up. Switch modes and watch it change.

A curtain between the two. Drag it across the part you care about.

Add it to your project

Answer four questions and copy one workflow file. The action finds the preview, takes the screenshots and cleans up after the pull request closes.

  1. Point it at your site

    Production is what your users see today. The preview is what this pull request would ship.

    Preview deploys

    • /
  2. Decide how strict it is

    A route passes while at most 0.1% of its pixels change. Up to 5% it is a warning; beyond that the check fails.
  3. Give it a bucket

    Screenshots go to an S3-compatible bucket you own, so private repos stay private. Save this as a repository secret named S3_CONFIG.
    S3_CONFIG
    {  "endpoint": "https://<account-id>.r2.cloudflarestorage.com",  "region": "auto",  "accessKeyId": "...",  "secretAccessKey": "...",  "bucket": "difftool-assets",  "forcePathStyle": true}
    Open its secrets
  4. Commit the workflow

    Push this file and open a pull request. The comment appears as soon as the preview is ready.
    .github/workflows/visual-diff.yml
    name: Visual diffon:  pull_request:    types: [opened, synchronize, reopened, closed]permissions:  pull-requests: write  deployments: readjobs:  visual-diff:    runs-on: ubuntu-latest    steps:      - uses: microlinkhq/difftool@master        with:          base: https://example.com          head: vercel          routes: |            - '/'          microlink-api-key: ${{ secrets.MICROLINK_API_KEY }}          s3-config: ${{ secrets.S3_CONFIG }}

Or hand the setup to a coding agent: the prompt carries your answers above, and any LLM with access to your repository can install difftool from it.

Questions

Something else? Open an issue on GitHub and it will get an answer.