text-visual-diff
    Preparing search index...

    text-visual-diff

    text-visual-diff

    Compare HTML source against plain text and highlight the differences.

    text-visual-diff extracts visible text from an HTML string (decoding entities along the way), diffs it word-by-word against a target plain-text string, and returns highlighted HTML for both sides — ready to drop into a browser, or consume as structured data.

    npm install text-visual-diff
    
    import { diffText } from "text-visual-diff";

    const result = diffText(
    "<p>Hello <b>world</b></p>",
    "Hello earth"
    );

    console.log(result.highlightedSource);
    // <mark class="diff-matched">Hello </mark>&lt;b&gt;<mark class="diff-unmatched">world</mark>&lt;/b&gt;

    console.log(result.highlightedTarget);
    // <mark class="diff-matched">Hello </mark><mark class="diff-added">earth</mark>

    console.log(result.extractedText);
    // "Hello world"

    console.log(result.segments);
    // [
    // { type: "matched", text: "Hello ", sourceStart: 3, sourceEnd: 9 },
    // { type: "unmatched", text: "world", sourceStart: 12, sourceEnd: 17 }
    // ]

    Main entry point. Strips tags from sourceHtml, decodes HTML entities, diffs the extracted text against targetText, and returns a DiffTextResult.

    Compare two plain-text strings and highlight the differences. Unlike diffText, no HTML tags are stripped and no entities are decoded — both inputs are treated as literal plain text.

    Field Type Description
    highlightedSource string Source HTML with highlight tags wrapped around matched/unmatched text
    highlightedTarget string Target plain text with highlight tags wrapped around matched/added text
    extractedText string Plain text extracted from the source HTML (entities decoded)
    targetText string The targetText argument, included for convenience
    segments HighlightSegment[] Structured segments describing each highlighted region in the source
    similarity number Dice similarity coefficient between 0 and 1

    All options default to "mark" for tags and "diff-matched" / "diff-unmatched" / "diff-added" for classes.

    Option Default Description
    matchedTag "mark" HTML tag for matched regions
    matchedClass "diff-matched" CSS class for matched regions
    unmatchedTag "mark" HTML tag for unmatched (removed) regions
    unmatchedClass "diff-unmatched" CSS class for unmatched regions
    addedTag "mark" HTML tag for added (target-only) regions
    addedClass "diff-added" CSS class for added regions
    showWhitespaceDiffs false When true, highlights whitespace-only differences
    Field Type Description
    type "matched" | "unmatched" | "added" Whether this region matched, was removed, or was added
    text string The visible text content inside this region
    sourceStart number Start offset (inclusive) within the original sourceHtml
    sourceEnd number End offset (exclusive) within the original sourceHtml
    import { useDiffText } from "text-visual-diff/react";

    function DiffView({ html, text }) {
    const result = useDiffText(html, text);
    return <div dangerouslySetInnerHTML={{ __html: result.highlightedSource }} />;
    }
    <div data-controller="text-visual-diff"
    data-text-visual-diff-source-html-value="&lt;p&gt;Hello&lt;/p&gt;"
    data-text-visual-diff-target-text-value="Hello">
    </div>
    import { DiffTextController } from "text-visual-diff/stimulus";
    application.register("text-visual-diff", DiffTextController);
    <script src="https://cdn.jsdelivr.net/npm/text-visual-diff/dist/text-visual-diff.iife.js"></script>
    <script>
    const result = TextVisualDiff.diffText("<p>Hello</p>", "Hello");
    </script>

    Two built-in CSS themes are available:

    /* Default — green matched, red unmatched, blue added */
    @import "text-visual-diff/theme/default";

    /* Subtle — lighter tones with dashed underlines */
    @import "text-visual-diff/theme/subtle";

    You can also write your own — the default class names are diff-matched, diff-unmatched, and diff-added.

    MIT