Search

Search the site

All components

Diff Viewer

A component for comparing two text versions with a diff viewer.

Changelog
Multi-line document diff with split view.

Compare two text versions side by side. Use the toolbar to switch split vs inline view and word vs line highlighting.

Diff View2 removals, 3 additions
Original
1## Authentication
2
3Sign in with email and password only.
4
5- Session expires after 24 hours
6- Password reset via email link
 
7- Admin roles managed in Clerk dashboard
Updated
1## Authentication
2
3Sign in with email, password, or SSO (Google / GitHub).
4
5- Session expires after 7 days with “Remember me”
6- Password reset via email link
7- Optional MFA for Pro accounts
8- Admin roles managed in Clerk dashboard
1import { DiffViewer } from "@/registry/ui/diff-viewer";
2
3const CHANGELOG_ORIGINAL = [
4 "## Authentication",
5 "",
6 "Sign in with email and password only.",
7 "",
8 "- Session expires after 24 hours",
9 "- Password reset via email link",
10 "- Admin roles managed in Clerk dashboard",
11].join("\n");
12
13const CHANGELOG_UPDATED = [
14 "## Authentication",
15 "",
16 "Sign in with email, password, or SSO (Google / GitHub).",
17 "",
18 "- Session expires after 7 days with “Remember me”",
19 "- Password reset via email link",
20 "- Optional MFA for Pro accounts",
21 "- Admin roles managed in Clerk dashboard",
22].join("\n");
23
24export function DiffViewerDefaultExample() {
25 return (
26 <div className="mx-auto w-full max-w-5xl space-y-6">
27 <p className="text-sm text-muted-foreground">
28 Compare two text versions side by side. Use the toolbar to switch split
29 vs inline view and word vs line highlighting.
30 </p>
31
32 <DiffViewer original={CHANGELOG_ORIGINAL} updated={CHANGELOG_UPDATED} />
33 </div>
34 );
35}
Compact inline
Compact inline diff

Compact inline diff

Diff View1 removals, 1 additions
Unified Diff
TT_UI_REGISTRY_TOKEN=sk_live_abc123
TT_UI_REGISTRY_TOKEN=sk_live_xyz789
1import { DiffViewer } from "@/registry/ui/diff-viewer";
2
3export function DiffViewerCompactInlineExample() {
4 return (
5 <div className="space-y-3 w-2/3 mx-auto max-w-5xl">
6 <h3 className="text-sm font-medium text-muted-foreground">
7 Compact inline diff
8 </h3>
9 <DiffViewer
10 original="TT_UI_REGISTRY_TOKEN=sk_live_abc123"
11 updated="TT_UI_REGISTRY_TOKEN=sk_live_xyz789"
12 splitView={false}
13 showLineNumbers={false}
14 highlightStyle="word"
15 variant="ghost"
16 className="w-full"
17 />
18 </div>
19 );
20}
Code refactor
Code refactor

Word-level highlighting works well for small refactors-rename a helper, extend a signature, or tighten a regex.

Diff View3 removals, 13 additions
Original
1export function formatPrice(cents: number) {
2 return `$${(cents / 100).toFixed(2)}`;
 
 
 
 
 
 
3}
4
5export function slugify(text: string) {
6 return text.trim().toLowerCase().replace(/\s+/g, "-");
 
 
 
 
7}
Updated
1export function formatPrice(
2 cents: number,
3 options?: { locale?: string; currency?: string },
4) {
5 return new Intl.NumberFormat(options?.locale ?? "en-US", {
6 style: "currency",
7 currency: options?.currency ?? "USD",
8 }).format(cents / 100);
9}
10
11export function slugify(text: string) {
12 return text
13 .trim()
14 .toLowerCase()
15 .replace(/[^\w\s-]/g, "")
16 .replace(/\s+/g, "-");
17}
1import { DiffViewer } from "@/registry/ui";
2
3const UTIL_ORIGINAL = [
4 "export function formatPrice(cents: number) {",
5 " return `$${(cents / 100).toFixed(2)}`;",
6 "}",
7 "",
8 "export function slugify(text: string) {",
9 ' return text.trim().toLowerCase().replace(/\\s+/g, "-");',
10 "}",
11].join("\n");
12
13const UTIL_UPDATED = [
14 "export function formatPrice(",
15 " cents: number,",
16 " options?: { locale?: string; currency?: string },",
17 ") {",
18 ' return new Intl.NumberFormat(options?.locale ?? "en-US", {',
19 ' style: "currency",',
20 ' currency: options?.currency ?? "USD",',
21 " }).format(cents / 100);",
22 "}",
23 "",
24 "export function slugify(text: string) {",
25 " return text",
26 " .trim()",
27 " .toLowerCase()",
28 ' .replace(/[^\\w\\s-]/g, "")',
29 ' .replace(/\\s+/g, "-");',
30 "}",
31].join("\n");
32
33export function DiffViewerCodeRefactorExample() {
34 return (
35 <div className="mx-auto w-full max-w-5xl space-y-3">
36 <p className="text-sm text-muted-foreground">
37 Word-level highlighting works well for small refactors-rename a helper,
38 extend a signature, or tighten a regex.
39 </p>
40 <DiffViewer
41 original={UTIL_ORIGINAL}
42 updated={UTIL_UPDATED}
43 highlightStyle="word"
44 />
45 </div>
46 );
47}

Installation & source

Install via the shadcn CLI or copy the registry files manually.

bash
npx shadcn@latest add @tt-ui/diff-viewer

Props

NameTypeDefaultDescription
originalstringRequiredThe original text to compare
updatedstringRequiredThe updated text to compare
highlightStylestringwordThe style of highlighting to use
showLineNumbersbooleantrueWhether to show line numbers
classNamestringTailwind classes for additional styling.
showPercentagebooleantrueWhether to show the percentage of the diff
showInstructionsbooleantrueWhether to show the instructions for the diff