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-diffnpm install @humanspeak/svelte-diffpnpm add @humanspeak/svelte-diffpnpm add @humanspeak/svelte-diffCompare 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
- Svelte Diff vs jsdiff — choose a rendered Svelte component or a JavaScript library that returns diff data, including word and line modes.
- Svelte Diff vs diff-match-patch — compare the underlying algorithm library with its reactive Svelte component integration.
- Svelte Diff vs diff2html — choose inline string comparison or a git-patch viewer with side-by-side files.
Next steps
- SvelteDiff API — every prop and precedence rule
- Expected Patterns — separate intentional variation from real changes
- Cleanup Modes — choose semantic, efficiency, or raw output
- Interactive Examples — edit values and inspect real output
- Comparisons — decide between this component and lower-level diff tools
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.