How it Works

The core idea is to diff the rendered HTML output instead of source data structures, given that apps render UI as HTML anyway. This bypasses the need for custom diff implementations.

Legend:

  • 🟧 Custom development effort required
  • 🟩 No custom development required (reusable)
  • ⚪ Unused in the diffing process

The diagram above shows two approaches to building diff views. The Custom Diff approach (🟧) requires building and maintaining specialized diff logic and custom renderers for each document type. This means more development effort and one-off solutions that don't generalize.

In contrast, the HTML Diff approach (🟩) leverages the fact that most applications ultimately render to HTML. Rather than building custom diff logic, it works directly with the rendered HTML output. This requires no adjustments from developers in terms of creating diffed data structures or modifying renderers—it simply takes your existing HTML and adds data-diff-status attributes to highlight changes. This approach generalizes across any application UI that renders to HTML, making it a reusable solution.

How Elements Are Tracked

HTML diff uses data-diff-key attributes to track elements across before/after states. Here's what happens:

Structure Preservation

Adding data-diff-key to elements only adds diff attributes—it doesn't modify the HTML structure:

  • ✅ No structural changes: Elements keep their original structure, attributes, and content
  • ✅ Only data-diff-status added: Elements get data-diff-status="added", "modified", or "removed"
  • ✅ Preserves layout: No new elements inserted, so CSS layouts (tables, flexbox, grid) remain intact

Before

|

After

|

Diff Result

|

Notice how in the diff result:

  • Table structure remains intact (no broken layout)
  • Only the data-diff-status attribute is added to the <td> elements
  • No wrapper elements or structural modifications

Diffing Modes

The progression of diffing granularity:

  1. No attributes: No diffing, HTML unchanged
  2. data-diff-key only: data-diff-status attributes added to changed elements
  3. data-diff-key + data-diff-mode="element": Explicit atomic element diffing (entire element marked as updated)
  4. data-diff-key + data-diff-mode="words": Granular word-level diffing with spans

This approach makes data-diff-key safe for complex layouts like tables, where inserting wrapper elements would break the structure.