Text Diff

Shows a word-level diff that makes changed numbers and invisible whitespace changes visible, so an edit can't slip through unseen.

StopsApproved an edit I didn't see

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/text-diff.json

The files land in your project. They're yours to edit.

Usage

text-diff-usage.tsx
import { TextDiff } from "@/components/ui/text-diff"

<TextDiff before={before} after={after} view={view} />

What it catches

  • Changed numbers, kept whole (1,250.50 is one token) and called out
  • Whitespace, line-break and zero-width character changes, drawn visibly
  • Identical texts, said plainly
  • Counts of words added and removed

Props

TextDiff props
PropTypeDefault
before* (required)

The original text.

string—
after* (required)

The changed text.

string—
view

`inline` interleaves changes; `split` shows before and after side by side.

"inline" | "split""inline"
showStats

Show the word counts and the "numbers changed" / "invisible change" callouts.

booleantrue
beforeLabel

Heading of the left column in split view.

string"Before"
afterLabel

Heading of the right column in split view.

string"After"
addedText

Templates: `{count}` is filled in.

string"+{count} added"
removedText

Count label for removed words.

string"−{count} removed"
numbersText

Lead-in before the changed numbers ("30 → 14, 4417 → 4471").

(count: number) => string(count) => (count === 1 ? "Number changed:" : `${count} n…
invisibleText

Count label for invisible-character changes.

(count: number) => string(count) => (count === 1 ? "1 invisible change" : `${count…
identicalText

Shown instead of the stats when the two texts are the same.

string"No changes"
srAddedLabel

Read before each change by screen readers.

string"added: "
srRemovedLabel

Screen-reader prefix for removed text.

string"removed: "

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Added and removed runs carry sr-only labels (srAddedLabel/srRemovedLabel)
  • Invisible characters have a title tooltip
  • Icons are aria-hidden

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Word-level, not semantic: reworded sentences show as remove + add
  • Very large diffs fall back to a coarser result past the memory budget

What it stops

Approved an edit I didn't see

Also known as

diff · text compare · track changes · review · contract · redline · word diff · diffchecker

Field type

Dependencies

Pairs well with