A client-side semantic YAML diff tool. Rust compiled to WebAssembly powers the diff engine, vanilla JavaScript handles the UI. No backend server, database, or external API — everything runs in the browser.
- Semantic YAML comparison — understands YAML structure (mappings, sequences, scalars) rather than comparing text lines
- Diff types:
Unchanged,Additions,Deletions,Modified - Myers-based array diffing — insertions and removals mid-sequence are detected using the Myers O(ND) diff algorithm (
similarcrate), replacing the old O(n*m) LCS approach. Falls back to positional comparison for extremely large sequences. - Recursive diff tree — nested objects and arrays produce a hierarchical diff with
has_diffpropagated from children. Recursion capped at 256 levels to prevent stack overflow. - Large file support (up to 100MB) — tiered behavior: auto-diff for files under 10MB, explicit "Run Diff" button for larger files, read-only mode for 50MB+, rejection above 100MB
- Auto-diff with debounce — comparison runs automatically as you type (400ms debounce) for small/medium files
- File upload — load
.yaml/.ymlfiles from disk into either editor panel with size validation - Line numbers with error highlighting — gutter synced to textarea scroll, error lines highlighted red
- Inline scalar display — scalar key-value pairs shown inline next to their key, only nested objects/arrays are collapsible
- Expandable additions/deletions — added or removed keys with nested structure are shown as collapsible trees, not flat
{}/[...] - Collapsible diff output — unchanged keys collapsed by default, additions (green), deletions (red), modified (amber) expanded
- Clickable diff filters — click Additions, Deletions, or Modified in the summary bar to filter the tree to only that type; click again to show all
- Progress loader — spinner with stage text ("Computing diff...", "Rendering...") shown during processing
- Storage quota warning — amber overlay on the affected editor when localStorage is full, instead of silent failure
- Simultaneous error reporting — both YAML parse errors shown at once if both inputs are invalid
- Runs entirely in the browser via WebAssembly
- Rust toolchain with
wasm-pack - Node.js 24+
npm install # Install JS dependencies
npm run serve # Start webpack dev server (compiles Rust to WASM automatically)Open http://localhost:8080, paste or upload two YAML documents — the diff tree renders automatically as you type.
npm run build # Production build → _site/ directorynpm run lint # Run all linters (ESLint + Prettier + cargo fmt + clippy)
npm run lint:fix # Auto-fix all (ESLint + Prettier + cargo fmt)lib.rs— WASM entry point. Exportscompute_diff(yone, ytwo)— parses both inputs, computes the full diff tree, and returns a JS array.diff.rs— Recursive diff engine. Compares mappings key-by-key, sequences via Myers diff algorithm (similarcrate), and scalars by value equality. StripsValue::Taggedwrappers for version-like strings. Additions/deletions of complex values produce full recursive child trees for expandable rendering. Diff results are serialized to plain JS objects in Rust to minimize WASM boundary overhead.
index.js— Async diff via singlecompute_diffWASM call with progress loader, debounced auto-diff (small files) or explicit "Run Diff" button (large files), file upload with size tiers, line number gutter with error highlighting, recursive diff tree rendering with collapsible nodes, clickable diff type filters, localStorage persistence (small files only).style.css— Tailwind CSS v4 with custom classes for editor gutter, diff tree color coding, and collapsible details/summary.
Webpack with @wasm-tool/wasm-pack-plugin compiles Rust to WASM during the build. Output goes to _site/.
GitHub Actions runs lint and build on push to main and on PRs. Deploy to GitHub Pages happens on push to main after both jobs pass.
Contributions are welcome! See CONTRIBUTING.md for setup instructions, coding guidelines, and how to submit a pull request.
Planned improvements for future releases:
- Input/Output Architecture — Replace textareas with CodeMirror 6 (virtual scrolling for large files, YAML syntax highlighting), add virtual scrolling for the diff tree, and switch from localStorage to IndexedDB for persistence
- Smarter Diffing — Move WASM diff to a Web Worker for non-blocking UI, add chunked per-key diffing for large mappings, and add lazy parsing to reduce peak memory usage
- Polish — Progress bar with cancel button during diff, memory monitoring with warnings, and diff export as JSON for files too large to render
See LICENSE for details.