## When to use

Anywhere the user needs to see what changed before approving, merging, or rolling back. Code review surfaces, content publishing flows, settings change-history, audit detail views. The right shape depends on the data: line-oriented text → code diff; paragraph-flow prose → prose diff; tabular fields → structured diff.

## Code diff — side by side

Two-column view with the old version on the left and the new on the right. Removed lines tinted danger; added lines tinted success. Compose two `code-ui line-numbers` blocks side-by-side; per-line tint comes from a `data-line-states` CSV (one entry per line: `unchanged`, `added`, or `removed`).

tokens.css +3 −2 · 5 lines changed
:root { --a-primary-bg: oklch(64% 0.15 245); --a-primary-fg: oklch(98% 0.01 245); --a-primary-border: oklch(60% 0.12 245); } :root { --a-primary-bg: oklch(64% 0.18 245); --a-primary-fg: oklch(98% 0.01 245); --a-primary-border: oklch(60% 0.15 245); --a-primary-hover: oklch(58% 0.18 245); }

## Code diff — inline (unified)

Single-column view with `+` and `−` line markers. Better for narrow columns and quick scan-reading. Compose `code-ui language="diff" line-numbers`; the `+`/`−`/space prefix on each line auto-resolves to `added` / `removed` / `unchanged` tint.

tokens.css — inline diff +3 −2
:root { - --a-primary-bg: oklch(64% 0.15 245); + --a-primary-bg: oklch(64% 0.18 245); --a-primary-fg: oklch(98% 0.01 245); - --a-primary-border: oklch(60% 0.12 245); + --a-primary-border: oklch(60% 0.15 245); + --a-primary-hover: oklch(58% 0.18 245); }

## Structured diff — field-level

For settings or records where the underlying shape is a key-value object, not lines of text. Each row shows the field name + old → new value pair. `description-list-ui` for layout; `tag-ui` with diff variants for the value pair.

Workspace settings — change preview 3 fields changed
Workspace name Adia Adia AI Default theme light auto Member invites Admin only Anyone with link

## Composition rules

- Color is the primary signal, not the only one — green/red tints carry the diff but icons and the `+`/`−` markers must work without color too. Color-blind users still need to read the diff.
- Side-by-side for review, inline for scan — side-by-side maps to "I'm comparing two versions", inline to "I'm reading the change". Offer both as a header toggle on review surfaces.
- Show context lines, not just the changes — a 5-line hunk with 3 changes is unreviewable without context; show ±3 unchanged lines around each change.
- Structured diff is for shaped data, not for code — if the field has a long string body, fall back to the line diff for that field. Don't tag-render multi-paragraph values.
- Counts in the header — "+3 −2" or "3 fields changed" lets the user calibrate before they start reading. Bare diffs feel arbitrarily long.

## See also

- code-ui — line-number gutter + language hint primitive.
- description-list-ui — structured diff layout.
- approvals — host pattern (review surfaces use diff for the body).
- richtext-ui — for prose-diff (body of a Notion/Google-Docs-style edit).