@design-parity/diff

中文文档
1.18.0发布于 2026/11/07Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 3724

Source-agnostic diff engine: consume a (DesignReference, CandidateRender) pair and emit a deterministic Verdict — a11y + i18n first, then token compliance, then visual diff.

原始使用文档
文档目录4 节
  1. Use
  2. Dimensions
  3. Scoped known differences
  4. Develop

@design-parity/diff

The source-agnostic diff engine. Consume a (DesignReference, CandidateRender) pair — from any adapter plus the candidate renderer — and emit a deterministic Verdict, a markdown summary, and a reference/candidate/diff triptych per image.

Per docs/PRINCIPLES.md: the engine runs only committed, deterministic rules/config — no model calls at run time, and the verdict leads with a11y + i18n, then token compliance, then the raw visual diff.

Use

import { diff } from "@design-parity/diff";

const { verdict, summary, triptychs } = await diff(reference, candidate, {
  repoRoot,          // image `uri`s resolve against this (default: cwd)
  outDir: "out",     // optional: write triptych-<key>.png here
  // config: { spacingTolerance: 0, pixelThreshold: 0.05, ... },
  // checksConfig: { contrastLevel: "AAA" },  // a11y/i18n thresholds
  // checks: myProvider,   // swap the default @design-parity/checks provider
});

verdict.status is pass | warn | fail (any error finding ⇒ fail); findings are ordered a11y → token → semantic → visual; verdict.visualScores maps each state/theme/size key to its differing-pixel fraction.

Dimensions

  • a11y + i18n — delegated to @design-parity/checks (#10) through a ChecksProvider seam: WCAG contrast, touch targets, semantic roles/labels, and i18n risks. defaultChecks wires the real package; inject a custom provider (or checksConfig) to override.
  • Token compliance — flatten the candidate's tree tokens and compare against the reference spec: numeric tokens honour a committed tolerance, typography matches exactly, colours match modulo a full-alpha suffix (with a same-role value fallback). When the design and code token vocabularies differ, a design-map.json tokens alias (code-name → design-name) canonicalises the reference to code names first, so e.g. design color/on-surface lines up with code onSurface.
  • Design system — a whole-table audit: the reference's resolved token table (DesignReference.themeTokens, e.g. the Figma Variables + type ramp) vs the code's resolved theme (SemanticTree.themeTokens), keyed through the same alias. Covers colours (mode-aware), the type ramp (exact, spec-driven), and the numeric radius/spacing scale (within the committed tolerance). Typography and shape/spacing names resolve through the alias first, then the Material role they denote (Body/Large → bodyLarge, radius/medium → medium). Findings carry detail.scope: "design-system" so the orchestrator reports each drift once per run, not once per screen.
  • Semantics — theme-coverage and structural (role/label) deltas.
  • Visual — per-pixel diff via pixelmatch, plus the triptych. A vector reference is rasterised at the candidate's width and the pair is aligned top-left, so a candidate's frame matters: a declared Image.gutter is cropped off first, and a repo whose renderer captures on a fixed canvas can set .design-parity.json's visual.candidateFrame: "crop-to-content" to crop the candidate to its drawn content — only against a reference whose own content reaches every edge, so a reference with a specified transparent margin is still compared whole (DiffConfig.visualCandidateFrame).

Everything is committed config (see config.ts); the same pair always yields the same verdict.

Scoped known differences

Pass exact catalog scope for any visual pair that should consume .design-parity/known-differences.json:

const result = await diff(reference, candidate, {
  repoRoot,
  knownDifferences: {
    scopes: {
      "default/light": {
        system: "m3",
        component: "IconButton/Tonal",
        previewId: "iconbutton-tonal__ideal__default__light",
        referenceId: "iconbutton-tonal-ideal-light",
        variant: "ideal/default/light",
        overrides: {},
        referenceSha256,
      },
    },
  },
});

The map key is the same state/theme/size key used by visualScores. Scope is explicit because these catalog identities cannot be reconstructed safely from a source-code handle. result.acceptances reports raw, accepted, and unaccepted separately plus the status of every record. The original verdict.visualScores, visual findings, and triptych are unchanged: accepting a difference never deletes the raw finding.

Only valid masks enter the scoring union. Gate evaluation precedes that union, and both inputs are split before any resampling, so a resolved/invalidated mask cannot suppress neighbouring pixels and an accepted delta cannot cancel an opposite regression at a mask edge.

Develop

npm run build --workspace @design-parity/diff
npm test --workspace @design-parity/diff

版本与发布记录

@design-parity/diff 共发布 102 个版本,首次发布于 2026/06/14;过去 12 个月发布了 102 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.18.0latest2026/11/074 天前
1.17.02026/10/2617 天前
1.16.12026/10/1824 天前
1.16.02026/10/1726 天前
1.15.02026/10/1528 天前
1.14.12026/10/1230 天前

关于 @design-parity/diff 的常见问题

@design-parity/diff 是什么?

Source-agnostic diff engine: consume a (DesignReference, CandidateRender) pair and emit a deterministic Verdict — a11y + i18n first, then token compliance, then visual diff.

如何安装 @design-parity/diff?

在项目目录运行 npm install @design-parity/diff,或使用 pnpm add / yarn add / bun add。

@design-parity/diff 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@design-parity/diff 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@design-parity/diff 可以商用吗?

@design-parity/diff 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@design-parity/diff 的下载量有多少?

根据 npm 官方下载统计,@design-parity/diff 在 2026/10/12 – 2026/11/10 这 30 天内被下载 3,724 次,日均约 124 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@design-parity/diff 还在维护吗?

最新版本 1.18.0 发布于 2026/11/07(4 天前);至今共发布 102 个版本,其中过去 12 个月发布了 102 个;首次发布于 2026/06/14。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。