iOS · macOS · native or React Native
Every screen in your app, checked on every PR
blinkdiff drives your app through a handful of declared journeys on every pull request, screenshots the checkpoints, diffs them against baselines committed in your repo, and comments with what moved. Intended changes are approved with one comment. It runs as a GitHub Action on your CI against your installed build, one to two minutes per flow.
How it works
- 01
Declare a journey
- 02
Drive, capture, diff
- 03
Comment, approve, merge
A short YAML file: bundle id, a few taps and types, screenshot checkpoints. Elements are addressed by accessibility label or identifier (a React Native testID). Ten lines covers a screen.
blinkdiff launches your installed build on the simulator and walks it through the journey, step by step. At each checkpoint it waits for the screen to settle, captures it, and compares the pixels to the committed baseline for that device and OS.
The PR gets one comment that updates in place: a table per flow and a link to every changed screenshot shown as baseline, current, and diff. Intended change? Comment /blinkdiff approve and blinkdiff commits the new baselines to the branch. The check goes green.
Why it works for any app
Native and React Native look the same to blinkdiff. SwiftUI, UIKit, AppKit and React Native apps are all driven the same way, from the same flow file, with the elements named the way your team already names them.
Baselines are PNGs in your git repo, keyed by device and OS, so they get history, blame and revert like everything else you commit.
Flows
A flow is the test. The steps are tap, type, clear, scroll, waitFor, menu and key on macOS, and screenshot, with optional ignore masks for regions that legitimately vary.
To write a flow for an unfamiliar screen, add - dump: home and blinkdiff writes that screen's accessibility tree next to the screenshot, listing every label and id you can tap.
Defaults for every flow live in one blinkdiff.yaml: device, appearance, thresholds, retries, masks.
Determinism
What blinkdiff pins
The simulator and OS, its appearance, and the parts of the screen that change on their own. Every capture waits for the screen to settle first. Two runs of an unchanged app come back identical, on the same machine or across machines.
What you pin
Seed the account. Mock the clock and network inside the app (launch args and env are passed through for exactly this). Mask what is legitimately volatile. Same rules as any snapshot test.
Retries
retries: 1 reruns a flow that failed to match. A one-off wobble passes on the second attempt; a real change fails every attempt and is reported.
Runs where your app already builds
blinkdiff is a GitHub Action. Your workflow builds the app for the simulator (or hands over the build from a job you already have), then the action boots the simulator, drives the flows, diffs, uploads the report and posts the comment. A second action handles /blinkdiff approve.
The runner, the artifacts and the baselines all live in your GitHub account.
Cost: macOS runner minutes you are mostly already paying for. Roughly one to two minutes per flow once the app is built, and blinkdiff can reuse the build from your existing job.
Pricing
Per repository. Unlimited flows, unlimited runs, every platform. Runs on your infrastructure, so there is no usage meter.
Free
one repository
- One flow
- Full CLI, action and report
- Enough to prove it in an afternoon
Repo
or $790/yr
- One repository
- Unlimited flows
- GitHub Action + approve bot
- Email support
Team
or $2,490/yr
- Up to 5 repositories
- Unlimited flows
- Priority email support, one business day
Buy outright
one payment · unlimited repos $4,900
- Perpetual license, up to 5 repositories
- One year of updates included
- Then $600/yr for updates, optional
- Skip it and keep the versions you have
Enterprise: invoicing, procurement paperwork, and a named person on email. $12,000/yr. info@blinkdiff.com
Questions
- How is this different from Meticulous / Chromatic / Percy?
- Those are web tools: they work from a DOM and a preview deploy. blinkdiff does the same job for iOS and macOS apps and runs on your CI. Meticulous records and replays real sessions; blinkdiff runs declared journeys, which is what makes its results deterministic.
- How is this different from Maestro, Detox, Appium, or an AI test runner?
- Those answer "does the app still work?" blinkdiff answers "does the app still look right?" It is a visual regression gate, and it sits alongside a functional test framework.
- Does it work with React Native / Expo?
- Yes. Elements are addressed by accessibility label or
testID. Build the app for the simulator (a Release build, so no Metro is needed on the runner); from there it is identical to native. - Real devices? Android?
- Simulator and macOS today; that's where determinism lives. Android is on the roadmap.
- What about passwords in screenshots?
- Password fields appear empty in screenshots by design. It is the same every run, so it compares clean, and screenshots stay free of passwords.
- What does it cost to run?
- Your own macOS runner minutes. On GitHub, macOS minutes count 10× against the free allowance and cost about $0.08 per minute beyond it. A typical check adds one to two minutes per flow on top of the app build you already run, and blinkdiff can reuse that build.
- Where do the screenshots live?
- In your repo, as PNGs, keyed by device and OS. Reports and comparison images go to your workflow artifacts and a branch in the same repo.