Code Diffs
Install the optional syntax highlighter alongside the Svelte package:
pnpm add @humanspeak/svelte-diff @tanstack/highlight@1.0.0pnpm add @humanspeak/svelte-diff @tanstack/highlight@1.0.0Import CodeDiff from @humanspeak/svelte-diff/code. Ordinary text-diff consumers
can keep importing the root without installing TanStack. Create your own
highlighter using individual language entries; register only what you use.
<script lang="ts">
import CodeDiff from '@humanspeak/svelte-diff/code'
import { createHighlighter } from '@tanstack/highlight/core'
import { ts } from '@tanstack/highlight/languages/ts'
import { createThemeCss } from '@tanstack/highlight/theme'
import { githubLightTheme } from '@tanstack/highlight/themes/github-light'
import { githubDarkTheme } from '@tanstack/highlight/themes/github-dark'
const highlighter = createHighlighter({ languages: [ts] })
const themeCss = createThemeCss({ light: githubLightTheme, dark: githubDarkTheme })
const before = 'const count = 10;\n'
const after = 'const count = 20;\n'
</script>
<svelte:head><svelte:element this={"style"}>{themeCss}</svelte:element></svelte:head>
<CodeDiff originalText={before} modifiedText={after} language="typescript" diffMode="line" {highlighter} /><script lang="ts">
import CodeDiff from '@humanspeak/svelte-diff/code'
import { createHighlighter } from '@tanstack/highlight/core'
import { ts } from '@tanstack/highlight/languages/ts'
import { createThemeCss } from '@tanstack/highlight/theme'
import { githubLightTheme } from '@tanstack/highlight/themes/github-light'
import { githubDarkTheme } from '@tanstack/highlight/themes/github-dark'
const highlighter = createHighlighter({ languages: [ts] })
const themeCss = createThemeCss({ light: githubLightTheme, dark: githubDarkTheme })
const before = 'const count = 10;\n'
const after = 'const count = 20;\n'
</script>
<svelte:head><svelte:element this={"style"}>{themeCss}</svelte:element></svelte:head>
<CodeDiff originalText={before} modifiedText={after} language="typescript" diffMode="line" {highlighter} />The theme helper supplies syntax colors. Its default dark selector is .dark;
toggle that class on an ancestor. For multiple independently themed blocks,
use scoped lightSelector / darkSelector, includeBaseStyles: false, and
scope the th-* color rules as in the editable example.
Theme generation belongs in the application, not the library component.
Whole-source context
Both complete sources are tokenized independently before their raw diff runs are composed. Deletions use original syntax; unchanged and inserted text use modified syntax. Editing the interior of a multiline comment or string therefore retains its classification. Repeated text is located using cumulative UTF-16 offsets, never substring searching.
CodeDiff always compares literal source. Named regex groups such as (?<year>\d{4}) remain code, and HTML-like input is rendered as escaped text.
It has no expected-pattern prop or capture parsing. Unknown or unregistered
languages fall back to plain text with TanStack’s default highlighter settings.
Modes, styles, and access
These examples explicitly use line mode to keep removed and inserted code lines together. The component default remains word; word and character modes are available for inline comparisons.
Word mode is the default; character and line modes are also available. Character cleanup defaults to off, and word/line skip cleanup entirely. JSON is highlighted source, not parsed or compared structurally. Unicode offsets use UTF-16; emoji grapheme atomicity is not guaranteed. Read the diff modes guide for comparison units and deadline fallbacks.
The output is one focusable, named pre/code region with semantic del and ins wrappers. Native Svelte escaping preserves source text without HTML injection.
Syntax spans use th-* classes. There is no default strike-through or library
foreground color. Override --svelte-diff-remove-bg and --svelte-diff-insert-bg on the block or an ancestor for change backgrounds, or add rendererClasses. ariaLabel names the overflow region; operation attributes label changes without
adding label text to the source body. Use keyboard arrow keys to scroll long lines.
The model preserves tabs, CR, LF, CRLF, final newlines, and Unicode code units. The browser HTML parser may normalize CR/CRLF during SSR; DOM or clipboard round-tripping of raw line endings is not guaranteed. Inputs are never normalized before diffing or tokenization.
Reactivity and limits
Changing only the modified source reuses original tokens. Changing language or highlighter identity invalidates both token stages. Mode, timeout, and cleanup options invalidate only diff computation. Theme, class, and operation-class changes reuse both tokenizations and diff results. Caches belong to each instance.
Computation and tokenization are synchronous. timeout governs the diff algorithm,
not highlighting or DOM rendering. This viewer has no patch format, hunks,
gutters, line numbers, side-by-side layout, folding, virtualization, workers,
editor parsing, callbacks, or headless entry.
See the CodeDiff API, types, and editable code example with copyable complete source.