Skip to content

DiffView component

DiffView compares two texts line by line and highlights the words that changed inside a changed line: two revisions of a post, two versions of a setting, a piece of code. It shows the texts side by side or one under the other, and folds long unchanged stretches behind a button. It has no dependencies, and the comparison itself is also exported as plain functions a server can call.

Data Display12 propsAccessibility notes

Playground

Change a prop on the right and the preview updates. Switch to Code to copy what you see.

Comparing two texts

Give it before and after. The default is split, two columns with line numbers; unified puts removed lines above added ones in one column. context sets how many unchanged lines stay visible around each change (3 by default). Longer unchanged runs fold behind a Show N unchanged lines button, and context={Infinity} shows everything.

<DiffView before={oldBody} after={newBody} beforeTitle="12 March" afterTitle="Current" />
<DiffView before={a} after={b} mode="unified" context={Infinity} monospace={false} />

Ignoring whitespace and wrapping

ignoreWhitespace treats lines that differ only in spaces and tabs as unchanged. wrapLines (on by default) wraps long lines; turn it off to scroll sideways, which suits code. monospace={false} uses the surrounding font, which suits prose.

<DiffView before={configA} after={configB} ignoreWhitespace wrapLines={false} />

Without the component

diffLines, diffWords and diffStats are plain functions, and the oks-ui/diff-view entry is not marked use client, so a Server Component or an API route can use them, for example to show 3 added, 1 removed in a list of revisions.

import { diffLines, diffStats } from "oks-ui/diff-view";

const { added, removed } = diffStats(diffLines(oldBody, newBody));

Props

The full public API for DiffView. Every prop is stable and intentionally typed.

Data

before / after

string

default: —

The older and the newer text.

Appearance

mode

"split" | "unified"

default: split

Side by side, or one column with removed lines above added ones.

showLineNumbers

boolean

default: true

The line-number columns.

wrapLines

boolean

default: true

Wraps long lines. false scrolls sideways.

monospace

boolean

default: true

A fixed-width font, for code. false uses the surrounding font, for prose.

classNames

Partial<Record<slot, string>>

default: —

Class per part: base, summary, table, row, lineNumber, content, fold.

Behavior & states

context

number

default: 3

Unchanged lines shown around each change. Longer unchanged runs fold behind a button. Infinity shows every line.

wordDiff

boolean

default: true

Highlights the changed words inside a replaced line.

ignoreWhitespace

boolean

default: false

Lines that differ only in spaces and tabs count as unchanged.

Content

showSummary

boolean

default: true

The line above the table (2 lines added, 1 removed).

beforeTitle / afterTitle

ReactNode

default: Before / After

Column titles, such as a revision name or a date.

labels

Partial<DiffViewLabels>

default: English

The text DiffView adds: removed, added, showUnchanged(count), summary(added, removed), noChanges, before, after. Also set app-wide with LocaleProvider.

Accessibility

  • A real table with column headers, named by its summary (2 lines added, 1 removed). The line-number columns have hidden header text.
  • Each removed or added line starts with hidden text (Removed:, Added:), so a change is not shown by colour alone. Changed words are real ins and del elements, and removed words are also struck through.
  • The tints sit under normal text and keep 4.5:1 contrast in light and dark themes.
  • A fold is a real button; opening it shows the lines in place.

Best practices

  • Give the two columns meaningful titles (a revision name or date) with beforeTitle and afterTitle.
  • Very large and very different texts fall back to one removed and one added block instead of an exact comparison, so the page stays fast.
  • For prose, set monospace to false and keep wrapLines on.
  • Translate the text DiffView adds with the labels prop or LocaleProvider.