Concepts
TurboSnap
How TurboSnap analyzes git changes to skip unchanged components and speed up visual testing.
Overview
TurboSnap dramatically reduces visual testing time by only capturing and comparing screenshots for components that have actually changed. On typical PRs, it skips 60-80% of screenshots.
How it works
Git Merge Base → Changed Files → File→Component Mapping → Affected ScreenshotsStep 1: Find the merge base
git merge-base HEAD origin/mainThis finds the common ancestor commit between your branch and the base branch, establishing the starting point for change detection.
Step 2: Get changed files
git diff --name-only <merge-base>..HEADLists all files that have changed since the branch diverged.
Step 3: Map files to screenshots
Each changed file is mapped to the screenshots it could affect:
| Changed file | Affected screenshots |
|---|---|
src/components/Button.tsx | Any page using <Button> |
src/styles/globals.css | All screenshots (global dep) |
src/pages/about.tsx | about screenshot |
README.md | None (skipped) |
Step 4: Filter screenshots
Only screenshots with at least one affected file are captured and compared. Everything else is skipped.
Global dependencies
Some files affect the entire application. When these change, TurboSnap falls back to testing everything:
turboSnap:
globalDeps:
- "src/styles/**" # Global CSS
- "tailwind.config.*" # Tailwind config
- "package.json" # Dependencies
- "src/lib/theme/**" # Theme systemConfiguration
turboSnap:
enabled: true
baseBranch: "main" # Branch to compare against
globalDeps:
- "src/styles/**"
includeUntracked: false # Include new untracked filesCLI usage
Standalone analysis
npx ui-inspect turbosnap --base-branch mainDuring builds
npx ui-inspect build --project proj_id --turbosnapCI considerations
- Set
fetch-depth: 0in your checkout step (GitHub Actions) so the full git history is available - TurboSnap requires a clean git state — uncommitted changes may affect results
- First build on a new branch always tests everything (no merge-base to compare against)
Performance impact
| Scenario | Without TurboSnap | With TurboSnap |
|---|---|---|
| 50 screenshots, 3 files changed | ~5 min | ~1 min |
| 100 screenshots, global CSS change | ~10 min | ~10 min (full) |
| 100 screenshots, 1 component change | ~10 min | ~30 sec |