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
| Input | Required | Default | Description |
|---|---|---|---|
base-url | Yes | Production URL to screenshot as baseline | |
head-url | Yes | PR preview URL to compare against | |
github-token | No | ${{ github.token }} | Token for posting PR comments |
threshold | No | 0.1 | Pixel match sensitivity (0-1, lower = more sensitive) |
fail-on-change | No | false | Fail the check if visual changes detected |
viewport-width | No | 1280 | Browser viewport width |
viewport-height | No | 800 | Browser viewport height |
wait-time | No | 1000 | ms to wait after page load for animations |
Outputs
| Output | Description |
|---|---|
changed | true if visual changes were detected |
change-percent | Percentage of pixels that changed |
changed-pixels | Number of pixels that changed |
diff-path | Path to the diff image |
base-screenshot-path | Path to the base screenshot |
head-screenshot-path | Path 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
- Screenshots both URLs with headless Chromium
- Computes pixel-level diff using pixelmatch
- Posts a summary comment on the PR with change percentage
- 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
| DiffGoblin | Percy | Chromatic | |
|---|---|---|---|
| Price | Free | $99-399/mo | $149+/mo |
| Setup | 3 lines of YAML | SDK integration | Storybook required |
| Screenshots | Full page | Component-level | Storybook stories |
| Self-hosted | Yes (it's a GH Action) | No | No |
| Open source | MIT | No | Partially |
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.