English | 简体中文
A local text and code diff tool
Pure-Rust diff engine · Native Tauri v2 window · No Electron
Get installers from Releases. Each release includes:
| Platform | File | Notes |
|---|---|---|
| macOS (Apple Silicon) | LiteDiff-*-macos-arm64.dmg |
Open and drag to Applications |
| macOS (Intel) | LiteDiff-*-macos-x64.dmg |
Same as above |
| Windows 10/11 (x64) | LiteDiff-*-windows-x64.exe |
Installer; no administrator rights required |
| Windows portable | LiteDiff-*-windows-x64.zip |
Extract and run; no installation needed |
Installation notes:
- macOS -- the build is ad-hoc signed but not notarized (notarization requires a paid Apple Developer account). If the first launch is blocked as an unverified app, open System Settings -> Privacy & Security -> Open Anyway, or run:
xattr -dr com.apple.quarantine /Applications/LiteDiff.app
- Windows -- run the
.exe. It installs for the current user and does not trigger a UAC prompt. If WebView2 is missing, the installer downloads it automatically.
Verify your download: every release includes SHA256SUMS.txt.
shasum -a 256 -c SHA256SUMS.txt # macOS
certutil -hashfile <file> SHA256 # WindowsDiff engine (pure Rust, no third-party runtime dependencies)
- Linear-space Myers with middle-snake and common prefix/suffix trimming; peak memory is O(N+M), and optimality is validated against a DP LCS oracle
- Word-level inline highlighting:
foo_bar->foo_bazhighlights onlybar/bazinstead of splitting every character - Ignore leading/trailing whitespace, all whitespace, or letter case; CRLF and LF are treated as equivalent
Interface
- Seven UI languages: Simplified Chinese, English, Traditional Chinese, Japanese, Spanish, German, and French; can follow the system language
- Side-by-side split view <-> unified inline view
- Fixed-row-height virtual scrolling; a 3,000+ line file renders only about 20-40 rows around the viewport
- Strict vertical and horizontal scroll synchronization between panes
- Automatic collapse of long unchanged regions, with per-region expand/collapse and expand/collapse-all controls
- Collapsed regions show the hidden line-number range; line-number width adapts to the file size
- Canvas-rendered minimap with click, drag, and keyboard navigation
- Three levels of change emphasis: row background, 3 px gutter marker, and word-level highlight
Interaction
- Paste directly into either side of the start screen (
Cmd+V), or drop a file onto one side Cmd+Nor the re-enter action returns to the paste screenCmd+Sperforms an atomic write to disk- Dark, light, and system themes
- Settings panel (
Cmd+,): accent color, red/green color-blind mode, highlight intensity, font size and line height, line numbers and minimap toggles, collapse threshold, leading/trailing whitespace, and case sensitivity
Git history
- Open any local repository and filter files by path
- Compare the working tree against any revision, or compare two revisions
- Historical revisions are always read-only. When comparing one against the working tree,
Cmd+Scan save only the working-tree file that holds a valid backend capability - Git reads disable repository hooks, fsmonitor, external diff, signature display, and unnecessary global configuration
- Local branch switching is restricted: dirty worktrees are refused rather than forced, and repository content filters are not allowed to execute
Comparison history
- Every comparison is stored locally and can be restored as a tab after reopening the app
- Grouped by day (Today / Yesterday / date), with per-item delete and clear-all actions
- Retention can be configured in Settings by days or by item count;
0means unlimited - Data stays in the local app-data directory and is never uploaded; comparisons larger than 4 MB are not recorded because truncating them would create a different diff
| Shortcut | Action |
|---|---|
| ⌘] / ⌘[ | Next / previous change |
| ⌘D | Toggle split / inline view |
| ⌘⇧W | Ignore leading/trailing whitespace and line endings |
| ⌘⌥E | Expand / collapse all unchanged regions |
| ⌘F | Find in the current comparison |
| ⌘S | Save |
| ⌘T / ⌘N | New tab (return to paste screen while keeping existing comparisons) |
| ⌘W | Close current tab |
| ⌘, | Open / close Settings |
| ⌘G | Open / close Git history |
| ⌘Y | Open / close comparison history |
Requires Rust 1.75+ and Node 18+.
# Dependencies
cd app && npm ci && cd ..
# Tests
cargo test # Rust
cd app && npm test # Frontend
# Package for macOS: produces .app and .dmg
./scripts/package-macos.sh
SKIP_DMG=1 ./scripts/package-macos.sh # .app only; faster for local iteration
# Package for Windows: produces an NSIS installer and portable zip (run on Windows)
powershell -ExecutionPolicy Bypass -File scripts\package-windows.ps1Releases are built by .github/workflows/release.yml. Pushing a v* tag builds on macOS (arm64 and x64) and Windows, attaches the artifacts and SHA256SUMS.txt to a draft release, and waits for manual confirmation before publishing.
For development, run the app in two terminals: cd app && npm run dev and cargo run -p litediff-app.
LiteDiff uses a lightweight, repository-native Spec-Driven Development workflow. Before changing behavior, read:
- CONTRIBUTING.md for setup, change levels, tests, and PR expectations
- docs/sdd/workflow.md for the L0-L3 process
- specs/product/litediff.md for the current product and safety baseline
- AGENTS.md for the repository-wide automation rules
Run the full quality gate with bash scripts/verify.sh on macOS/Linux/Git Bash, or powershell -ExecutionPolicy Bypass -File scripts\verify.ps1 on Windows.
- macOS 11+ (Big Sur or later), with native builds for both Apple Silicon and Intel; installers are about 2.3 MB
- Windows 10 / 11 (x64) with WebView2 (included in Windows 11 and recent Windows 10 builds; setup downloads it when missing)
Svelte 5 frontend --IPC (Session / SessionUpdate)--> Tauri v2 backend --> litediff-core
Three key decisions
- Send immutable session snapshots over IPC: the initial result includes both documents, while option-only recomputes use
SessionUpdateand omit unchanged source text - Single scroll authority: panels only report
scrollTop;Appstores one value and feeds it back to both panes so they stay pixel-aligned - Collapse is a projection:
buildDisplay()projects hunks into display items. Display indexes and source-line indexes are separate coordinate systems, so every jump must go through that projection
cargo test # Rust
npm test # Frontend (run from app/)The core Rust guarantee is optimality validation: a brute-force DP LCS implementation serves as an oracle, asserting that the match count equals the LCS length across random low-alphabet inputs. This caught two intermediate-snake overlap bugs during development.
| Limitation | Reason |
|---|---|
| In-place editing | Conflicts with virtual scrolling, which recycles focused DOM nodes |
| Accept-change arrows | Require the in-place editing buffer model |
| Very large files | Whole-file comparison only; no chunked streaming yet |