logo svelte /diff v0.4.3

Getting Started

@humanspeak/svelte-diff is a focused Svelte 5 component for comparing two strings. It runs the diff-match-patch algorithm, optionally cleans the result for readability, and renders each change as real Svelte markup.

Installation

npm install @humanspeak/svelte-diff
npm install @humanspeak/svelte-diff
pnpm add @humanspeak/svelte-diff
pnpm add @humanspeak/svelte-diff

Compare two strings in Svelte

To build an inline Svelte diff viewer, pass the original and modified strings to SvelteDiff. Enable cleanupSemantic to make edits in prose easier to read:

<script lang="ts">
    import SvelteDiff from '@humanspeak/svelte-diff'

    const before = 'Ship the small release on Tuesday.'
    const after = 'Ship the polished release on Thursday.'
</script>

<p class="diff-output">
    <SvelteDiff originalText={before} modifiedText={after} cleanupSemantic />
</p>
<script lang="ts">
    import SvelteDiff from '@humanspeak/svelte-diff'

    const before = 'Ship the small release on Tuesday.'
    const after = 'Ship the polished release on Thursday.'
</script>

<p class="diff-output">
    <SvelteDiff originalText={before} modifiedText={after} cleanupSemantic />
</p>

By default, removed text is red with a strike-through, inserted text is green, and unchanged text is unstyled. Unstyled unchanged text uses compact DOM without wrapper spans; pass compact={false} when migrating selectors or styles that require the legacy equal spans. Text is escaped by Svelte; the component does not inject an HTML string.

Try the live diff viewer or the basic diff example. For dates, versions, and generated IDs that are supposed to change, use expected patterns to label those values separately.

Reactive inputs

Both required props are reactive. If either string changes, the component recomputes the diff.

<script lang="ts">
    import SvelteDiff from '@humanspeak/svelte-diff'

    let originalText = $state('Hello from Svelte.')
    let modifiedText = $state('Hello from Svelte 5.')
</script>

<textarea bind:value={originalText}></textarea>
<textarea bind:value={modifiedText}></textarea>

<SvelteDiff {originalText} {modifiedText} />
<script lang="ts">
    import SvelteDiff from '@humanspeak/svelte-diff'

    let originalText = $state('Hello from Svelte.')
    let modifiedText = $state('Hello from Svelte 5.')
</script>

<textarea bind:value={originalText}></textarea>
<textarea bind:value={modifiedText}></textarea>

<SvelteDiff {originalText} {modifiedText} />

Recommended readable defaults

For prose and user-facing copy, semantic cleanup is usually the best starting point:

<SvelteDiff
    {originalText}
    {modifiedText}
    cleanupSemantic={true}
    timeout={1}
/>
<SvelteDiff
    {originalText}
    {modifiedText}
    cleanupSemantic={true}
    timeout={1}
/>

For machine-like strings where every small edit matters, keep semantic cleanup off and use the default efficiency cleanup.

Styling with classes

Use rendererClasses when you want to keep the default <span> markup:

<SvelteDiff
    {originalText}
    {modifiedText}
    rendererClasses={{
        remove: 'diff-remove',
        insert: 'diff-insert',
        equal: 'diff-equal',
        expected: 'diff-expected'
    }}
/>
<SvelteDiff
    {originalText}
    {modifiedText}
    rendererClasses={{
        remove: 'diff-remove',
        insert: 'diff-insert',
        equal: 'diff-equal',
        expected: 'diff-expected'
    }}
/>

Use child snippets when you need different elements, attributes, icons, or animation. See Custom Rendering.

Choosing a diff tool

Next steps

Choose a comparison unit

Character is the default and retains the existing cleanup behavior. Use diffMode="word" for complete changed words or diffMode="line" for complete changed lines. Both token modes skip cleanup.

<script lang="ts">
    import SvelteDiff from '@humanspeak/svelte-diff'
    const before = 'The cat sleeps.'
    const after = 'The car sleeps.'
</script>

<SvelteDiff originalText={before} modifiedText={after} diffMode="word" />
<script lang="ts">
    import SvelteDiff from '@humanspeak/svelte-diff'
    const before = 'The cat sleeps.'
    const after = 'The car sleeps.'
</script>

<SvelteDiff originalText={before} modifiedText={after} diffMode="word" />

Read the mode guide, edit the word example, or try the line example. JSON input remains plain text; sentence and structural JSON modes are unsupported.