A powerful, customizable diff-match-patch component for Svelte with TypeScript support.
npm i -S @humanspeak/svelte-diff-match-patch
Or with your preferred package manager:
pnpm add @humanspeak/svelte-diff-match-patch
yarn add @humanspeak/svelte-diff-match-patch
<script lang="ts">
    import SvelteDiffMatchPatch from '@humanspeak/svelte-diff-match-patch'
    let originalText = $state(`I am the very model of a modern Major-General,
I've information vegetable, animal, and mineral,
I know the kings of England, and I quote the fights historical,
From Marathon to Waterloo, in order categorical.`)
    let modifiedText = $state(`I am the very model of a cartoon individual,
My animation's comical, unusual, and whimsical,
I'm quite adept at funny gags, comedic theory I have read,
From wicked puns and stupid jokes to anvils that drop on your head.`)
    const onProcessing = (timing, diff) => {
        console.log('Diff timing:', timing)
        console.log('Diff result:', diff)
    }
</script>
<SvelteDiffMatchPatch
    {originalText}
    {modifiedText}
    timeout={1}
    cleanupSemantic={false}
    cleanupEfficiency={4}
    {onProcessing}
    rendererClasses={{
        remove: 'diff-remove',
        insert: 'diff-insert',
        equal: 'diff-equal'
    }}
/>
<style>
    :global(.diff-remove) {
        background-color: #ffd7d5;
        text-decoration: line-through;
    }
    :global(.diff-insert) {
        background-color: #d4ffd4;
    }
</style>
The package is written in TypeScript and includes full type definitions:
import type {
    SvelteDiffMatchPatchTiming,
    SvelteDiffMatchPatchDiff,
    SvelteDiffMatchPatchProps
} from '@humanspeak/svelte-diff-match-patch'
| Prop | Type | Default | Description | 
|---|---|---|---|
| originalText | string | 
- | The original text to compare against | 
| modifiedText | string | 
- | The modified text to compare with original | 
| timeout | number | 
1 | Timeout in seconds for diff computation | 
| cleanupSemantic | boolean | 
false | Enable semantic cleanup for better readability | 
| cleanupEfficiency | number | 
4 | Efficiency cleanup level (0-4) | 
| onProcessing | function | 
- | Callback for timing and diff information | 
| rendererClasses | object | 
- | CSS classes for diff highlighting | 
You can customize how the diff is rendered using Svelte snippets. This gives you full control over the HTML structure and styling of each diff part.
<script lang="ts">
    import SvelteDiffMatchPatch from '@humanspeak/svelte-diff-match-patch'
    let originalText = $state(`I am the very model of a modern Major-General,
I've information vegetable, animal, and mineral,
I know the kings of England, and I quote the fights historical,
From Marathon to Waterloo, in order categorical.`)
    let modifiedText = $state(`I am the very model of a cartoon individual,
My animation's comical, unusual, and whimsical,
I'm quite adept at funny gags, comedic theory I have read,
From wicked puns and stupid jokes to anvils that drop on your head.`)
</script>
<SvelteDiffMatchPatch {originalText} {modifiedText}>
    {#snippet remove(text: string)}
        <span class="diff-snippet-remove">{text}</span>
    {/snippet}
    {#snippet insert(text: string)}
        <span class="diff-snippet-insert">{text}</span>
    {/snippet}
    {#snippet equal(text: string)}
        <span class="diff-snippet-equal">{text}</span>
    {/snippet}
    {#snippet lineBreak()}
        <br /><br />
    {/snippet}
</SvelteDiffMatchPatch>
<style>
    :global(.diff-snippet-remove) {
        background-color: #ffd7d5;
        text-decoration: line-through;
    }
    :global(.diff-snippet-insert) {
        background-color: #d4ffd4;
    }
</style>
| Snippet | Parameters | Description | 
|---|---|---|
| remove | text | 
Renders removed text (in originalText only) | 
| insert | text | 
Renders inserted text (in modifiedText only) | 
| equal | text | 
Renders unchanged text (in both texts) | 
| lineBreak | - | Renders line breaks between diff sections | 
You can use these snippets to:
If you don't provide snippets, the component will use the default rendering with the rendererClasses prop.
The component emits a processing event with timing and diff information:
<script lang="ts">
    import type {
        SvelteDiffMatchPatchTiming,
        SvelteDiffMatchPatchDiff
    } from '@humanspeak/svelte-diff-match-patch'
    const onProcessing = (timing: SvelteDiffMatchPatchTiming, diff: SvelteDiffMatchPatchDiff) => {
        console.log('Diff computation time:', timing.computeTime)
        console.log('Cleanup time:', timing.cleanupTime)
        console.log('Total changes:', diff.length)
    }
</script>
<SvelteDiffMatchPatch {originalText} {modifiedText} {onProcessing} />
When cleanupSemantic is enabled, the diff algorithm will:
The cleanupEfficiency level (0-4) controls how aggressively the algorithm:
timeout valuecleanupSemantic for better readability in small to medium textscleanupEfficiency for better performance in large textsonProcessing callback for timing informationMIT ยฉ Humanspeak, Inc.
Made with โฅ by Humanspeak