A line-by-line diff of two strings — the before/after view a screen needs when it has to show what changed: a config or settings change, a record edited in an admin panel, a document revision, a webhook payload against the last one, an audit-log entry, a restored backup next to what is live, or the edit an AI agent is proposing before the user accepts it. Common asks it answers: "react diff component", "diff viewer react", "show what changed between two strings", "before and after comparison react", "git style diff in react", "unified diff component", "side by side diff react", "split diff view", "react-diff-viewer alternative", "diff2html alternative", "jsdiff without the rendering", "diff two json strings visually", "show config changes in an admin panel", "audit log before and after", "document revision comparison", "review an AI agent's proposed edit before accepting it", "collapse unchanged lines in a diff", "colorblind accessible diff", "diff in a react server component", "diff without a client bundle". Pass before and after and it renders a git-style diff, unified by default or side by side with view="split". Unchanged lines collapse into a counted gap, so a 400-line file with a three-line change shows three lines and a summary instead of 400; context sets how many surrounding lines survive and context={Infinity} shows the whole text. Both line-number gutters are select-none, so selecting the diff copies the code and not a column of numbers. CRLF and LF are folded together, because a file that changed only its line endings would otherwise report every single line as rewritten. It is meaning-first rather than colour-first: every changed row carries a + or - sign and a screen-reader-only "Added line:" / "Removed line:" prefix, so the diff still reads for someone who cannot tell the red and green backgrounds apart — conveying the change by colour alone, which fails WCAG 1.4.1, is the single most common defect in a hand-rolled diff. The table also gets an sr-only caption stating how many lines were added and removed. The diff is a longest-common-subsequence over lines with the shared prefix and suffix trimmed off first, which keeps a large document with a small edit fast (a 4,000-line file with one changed line diffs in well under a millisecond) and makes an appended line read as appended instead of shifting everything by one. Pathologically large inputs degrade to "this block was replaced" rather than allocating a table of hundreds of megabytes during a render. No dependencies, no diff library and no hooks, so it renders inside a React server component without a "use client" of its own and ships no client JavaScript — which is the common case, because the text being compared has usually just been fetched on the server. Official shadcn/ui has no diff component of any kind — the string "diff" is zero hits across all 62 of its fetchable items (measured 2026-09-27): its table is an unstyled table and its chart is a Recharts wrapper, and neither computes or displays a change. Distinct from the pulld pieces it sits beside: code-block shows one snippet with its own copy button and makes no claim about change, json-viewer explores a single object by folding it, ansi-log replays terminal output with its colour codes intact, highlight-text marks matches inside one string, read-more truncates one passage, and image-comparison is the same before/after question asked of two pictures with a slider rather than of two texts line by line.
pnpm dlx shadcn@latest add "https://pulld.pages.dev/r/diff-view.json"