DiffGoblin Action

April 15, 2026 · View on GitHub

Visual regression testing for pull requests. Screenshot your production site and PR preview, get a pixel-level diff posted as a PR comment. Free. Open source.

Stop merging visual regressions. Stop paying $149/mo for Percy.

Quick Start

Add to .github/workflows/visual-diff.yml:

name: Visual Diff
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  visual-diff:
    runs-on: ubuntu-latest
    steps:
      - uses: neg-0/diffgoblin-action@v1
        with:
          base-url: 'https://your-site.com'
          head-url: 'https://your-pr-preview.vercel.app'

That's it. Every PR gets a comment showing what changed visually.

Works with Preview Deploys

Pair with Vercel, Netlify, or any preview deploy system:

name: Visual Diff
on:
  deployment_status:

jobs:
  visual-diff:
    if: github.event.deployment_status.state == 'success'
    runs-on: ubuntu-latest
    steps:
      - uses: neg-0/diffgoblin-action@v1
        with:
          base-url: 'https://your-production-site.com'
          head-url: ${{ github.event.deployment_status.target_url }}

Inputs

InputRequiredDefaultDescription
base-urlYesProduction URL to screenshot as baseline
head-urlYesPR preview URL to compare against
github-tokenNo${{ github.token }}Token for posting PR comments
thresholdNo0.1Pixel match sensitivity (0-1, lower = more sensitive)
fail-on-changeNofalseFail the check if visual changes detected
viewport-widthNo1280Browser viewport width
viewport-heightNo800Browser viewport height
wait-timeNo1000ms to wait after page load for animations

Outputs

OutputDescription
changedtrue if visual changes were detected
change-percentPercentage of pixels that changed
changed-pixelsNumber of pixels that changed
diff-pathPath to the diff image
base-screenshot-pathPath to the base screenshot
head-screenshot-pathPath to the head screenshot

Use Outputs in Your Workflow

- uses: neg-0/diffgoblin-action@v1
  id: diff
  with:
    base-url: 'https://prod.example.com'
    head-url: 'https://preview.example.com'
    fail-on-change: 'true'

- name: Upload diff artifacts
  if: steps.diff.outputs.changed == 'true'
  uses: actions/upload-artifact@v4
  with:
    name: visual-diff
    path: diffgoblin-output/

How It Works

  1. Screenshots both URLs with headless Chromium
  2. Computes pixel-level diff using pixelmatch
  3. Posts a summary comment on the PR with change percentage
  4. Outputs diff data for your workflow to use (upload artifacts, gate merges, etc.)

The diff image highlights changed pixels in red. Download it from the workflow artifacts to see exactly what changed.

Why DiffGoblin?

  • Free and open source. No per-screenshot pricing. No seat fees.
  • Zero config. Two URLs and you're done.
  • Updates comments. Doesn't spam — updates the same comment on each push.
  • CI-native. Use outputs to gate merges, upload artifacts, or trigger alerts.
  • Fast. One headless browser, two screenshots, done.

Compared to Percy/Chromatic

DiffGoblinPercyChromatic
PriceFree$99-399/mo$149+/mo
Setup3 lines of YAMLSDK integrationStorybook required
ScreenshotsFull pageComponent-levelStorybook stories
Self-hostedYes (it's a GH Action)NoNo
Open sourceMITNoPartially

DiffGoblin trades component-level granularity for simplicity and zero cost. If you just want to see "did my PR break the visual layout?" — this is it.

License

MIT

Built by ShipGoblin

Part of the DiffGoblin visual diff toolkit.