β οΈ Status: Experimental / 0.x This project is in early development. APIs may change without notice and are not production-ready. Feedback and contributions are welcome!
Design-to-implementation comparison tool that evaluates how closely an implemented UI matches a Figma design with pixel-level precision, color accuracy (ΞE2000), and automated quality scoring.
π Full Documentation
- Getting Started - Installation and quickstart
- CLI Reference - Complete command options
- Concepts - Anchors, quality gates, content basis
- CI Integration - GitHub Actions and CI setup
- Local Testing - Pack/link workflows for contributors
- Troubleshooting - Common issues and solutions
- Plugins - Plugin development guide
- Experimental Features - MCP and AI integration
- API Reference - TypeScript API documentation
Global install (for CLI usage):
npm install -g @uimatch/cli playwright
npx playwright install chromium
export FIGMA_ACCESS_TOKEN="figd_..."Project install (for development/CI):
npm install -D @uimatch/cli playwright
npx playwright install chromiumNote: The examples below assume @uimatch/cli is already installed (globally or as a dev dependency).
npx @uimatch/cli compare \
figma=<fileKey>:<nodeId> \
story=http://localhost:6006/?path=/story/button \
selector="#root button"Try without installing:
If you want to run a quick test without installation:
npx -p @uimatch/cli uimatch compare \
figma=<fileKey>:<nodeId> \
story=http://localhost:6006/?path=/story/button \
selector="#root button"npx @uimatch/cli compare \
figma=<fileKey>:<nodeId> \
story=http://localhost:6006/?path=/story/button \
selector="#root button" \
outDir=./uimatch-reportsπ See Getting Started for detailed setup
- Pixel-perfect comparison - Visual diff with content-aware pixelmatch
- Color accuracy - Perceptual color difference with ΞE2000
- Design Fidelity Score - Automated 0-100 quality scoring (DFS)
- Figma integration - Direct API access, MCP server support, or bypass mode
- Quality gates - Configurable pass/fail thresholds with profiles
- Stable selectors - AST-based anchors plugin for refactor-resistant targeting
- CI-ready - GitHub Actions integration with caching and artifacts
npx @uimatch/cli compare \
figma=... story=... selector=... \
size=strict profile=component/strictnpx @uimatch/cli compare \
figma=... story=... selector=... \
size=pad contentBasis=intersectionπ See CLI Reference for selector anchors, suite mode, and all options
Minimal GitHub Actions example:
name: uiMatch QA
on: [pull_request]
jobs:
compare:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install
run: |
npm install -g @uimatch/cli playwright
npx playwright install --with-deps chromium
- name: Compare
env:
FIGMA_ACCESS_TOKEN: ${{ secrets.FIGMA_TOKEN }}
run: |
npx @uimatch/cli compare \
figma=${{ secrets.FIGMA_FILE }}:${{ secrets.FIGMA_NODE }} \
story=https://storybook.com/?path=/story/button \
selector="#root button" \
outDir=uimatch-reports \
profile=component/strict
- name: Upload artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: uimatch-reports
path: uimatch-reports/π See CI Integration Guide for caching, bypass mode, suite configurations, and complete setup
Built-in profiles for different use cases:
component/strict- Pixel-perfect for design systemscomponent/dev- Development tolerancepage-vs-component- Loose layout comparisonpage/text-doc- Text-heavy pages (Terms, Privacy)
npx @uimatch/cli compare \
figma=... story=... selector=... \
profile=component/strictπ See CI Integration Guide for detailed thresholds and parameters
At a high level:
- Fetch frame PNG from Figma (API / MCP / bypass)
- Capture implementation screenshot via Playwright
- Compare pixels + styles in
@uimatch/core - Apply quality gates and compute DFS (0β100)
- Report pass/fail and diff artifacts (for CI)
π See Concepts - Architecture for detailed diagrams and component explanation
- Node.js 20.19+ / 22.12+
- pnpm 9.15.4+
- Bun 1.x (test runner)
pnpm install
pnpm build
pnpm test# Smoke test (no Figma/Storybook required)
pnpm build
node packages/uimatch-cli/dist/cli/index.js compare \
figma=bypass:test \
story="data:text/html,<div style='width:10px;height:10px;background:red'></div>" \
selector="div" dpr=1 size=padπ See Local Testing Guide for pack/link workflows
Run diagnostics:
npx @uimatch/cli doctorCommon issues:
| Issue | Solution |
|---|---|
| Browser not found | npx playwright install chromium |
| Figma token missing | export FIGMA_ACCESS_TOKEN="figd_..." |
| Want to see browser | export UIMATCH_HEADLESS=false |
π See Troubleshooting Guide for complete solutions
Public (npm):
@uimatch/cli- CLI tool@uimatch/selector-anchors- AST-based selector plugin@uimatch/selector-spi- Plugin interface types@uimatch/shared-logging- Logging utilities
Internal:
@uimatch/core- Comparison engine@uimatch/scoring- DFS calculator
ui-match/
βββ packages/
β βββ uimatch-cli/ # CLI entry point
β βββ uimatch-core/ # Comparison engine
β βββ uimatch-scoring/ # DFS calculation
β βββ uimatch-selector-spi/ # Plugin interface
β βββ uimatch-selector-anchors/ # AST plugin
β βββ shared-logging/ # Logging utils
βββ docs/ # Documentation site
These markdown-based skills support AI-assisted workflows (Claude Code) and provide task-focused guides and references.
- Visual Compare:
experiments/skills/uimatch-compare/SKILL.md - Suite (Batch):
experiments/skills/uimatch-suite/SKILL.md - Text Diff:
experiments/skills/uimatch-text-diff/SKILL.md
Shared references:
experiments/skills/_shared/uimatch-advanced-settings.mdexperiments/skills/_shared/uimatch-common-env.md
π Important: export FIGMA_ACCESS_TOKEN in your shell (the CLI does not read .env automatically).
π Prefer FILE_KEY:NODE_ID for Figma references; if you pass a full Figma URL, always quote it in the shell.
Contributions welcome! See Local Testing for development workflows.
MIT