Engineering Journal
Pdf Processor
Pdf Processor

Most Diff UIs Are Just Colored Spans. That Is Not a Diff.

2026-06-03

TLDR

Token-based inline diff wrappers (e.g. jsdiff wrapping added/removed text in inline <span> tags) fail for document-level side-by-side comparison interfaces because token streams do not preserve line number alignment or vertical row correspondence. Building a true line-by-line diff engine requires a two-pass architecture: Pass 1 executes line-array diffing (diffArrays), while Pass 2 pairs removed and added line blocks 1-to-1 into aligned row objects.
Diff ImplementationLine Number AlignmentVertical Pane SyncIdeal Use Case
Token-Based Inline SpansFails (Tokens break line alignment)Fails (Panes drift vertically)Short inline text fields
Line-Oriented Row Pairing100% (Line-for-line alignment)100% (Synchronized row heights)Multi-page document comparison

Technical implementation: two-pass line pairing algorithm

// Two-Pass Line Diff Engine: Pair removed and added lines 1-to-1 for side-by-side alignment
export function buildLineAlignedDiffPairs(lineDiffResults) {
  const alignedRows = [];

for (const part of lineDiffResults) { if (!part.added && !part.removed) { // Unchanged lines: Pair identical left and right lines for (const line of part.value) { alignedRows.push({ left: line, right: line, type: 'equal' }); } } else if (part.removed) { // Buffer removed lines block alignedRows.push({ _removedLines: part.value }); } else if (part.added) { const prevBlock = alignedRows[alignedRows.length - 1];

if (prevBlock?._removedLines) { // Pair removed and added blocks 1-to-1 by index const removed = prevBlock._removedLines; const added = part.value; alignedRows.pop(); // Remove buffered block

const maxLen = Math.max(removed.length, added.length); for (let i = 0; i < maxLen; i++) { alignedRows.push({ left: i < removed.length ? removed[i] : null, right: i < added.length ? added[i] : null, type: i < removed.length && i < added.length ? 'change' : (i < removed.length ? 'remove' : 'add') }); } } else { for (const line of part.value) { alignedRows.push({ left: null, right: line, type: 'add' }); } } } }

return alignedRows; }

Rule of thumb: Execute line-array diffing and 1-to-1 row pairing before running inline token diffing on modified document lines.
Read this post in the full Engineering Journal →