About diffvoid.com
diffvoid.com is a secure, private, browser-based text comparison tool. All processing happens locally in your browser—your text never leaves your device.
Key Features
- Privacy first: No server uploads, no tracking, no analytics. Everything stays in your browser.
- Line-aware Myers diff: A first-party Myers implementation preserves exact matching-line anchors when lines are inserted or removed.
- Bounded row alignment: Unmatched hunks use deterministic full or banded dynamic programming to pair similar modified lines. If reliable pairing exceeds the shared work budget, the lines are conservatively shown as missing and added.
- Character-level diff: Selected modified pairs are compared by grapheme and stored as compact UTF-16 change ranges instead of permanent per-character objects.
- Invisible character detection: Highlights zero-width spaces, non-breaking spaces, and other hidden Unicode characters that can cause subtle bugs.
- Confusable character detection: Marks common Greek and Cyrillic homographs that look like Latin letters, with tooltips explaining the real Unicode character.
- Exact and clean copying: Copy L/R always copies the complete original source after a comparison, including rows outside the visible window and trailing newlines. When invisible characters are detected, Clean L/R also appears to normalize hidden spacing characters and remove soft hyphens and BOM characters.
- Adjustable panels: Drag the center divider to adjust left/right panel widths. Double-click to reset to 50/50.
- Clear button: One-click to clear both panels and reset to default view.
- Dark mode: Toggle between light and dark themes with preference saved locally.
- Cost-based Web Worker processing: Comparisons normally run in a background worker. Only input proven small enough may fall back to synchronous processing when a worker cannot be created.
- Virtualized rendering: Both panes mount only the same visible row window, with hard row and DOM-node caps and rendering work split across animation frames.
- Long-line previews: Dense lines over 20,000 code units are shown as paged previews around their changes while exact copying continues to use the complete source.
How It Works
A lightweight scan first validates the input and estimates its cost. Accepted comparisons normally run in a same-origin Web Worker. If worker creation is unavailable, only a comparison classified as safely small may run synchronously; heavy input is stopped with an instruction to serve the app over HTTP or compare smaller sections.
For that reason, opening the app from a file:// URL is not recommended. If worker creation fails
immediately, only a safely small comparison may fall back to synchronous processing. Serve the
public/ directory over HTTP for the complete comparison flow.
Myers line diff establishes exact anchors. Inside each unmatched hunk, a bounded dynamic-programming pass selects similar modified-line pairs with deterministic tie-breaking. It uses a full matrix for small hunks and a banded matrix for larger ones. If the remaining budget cannot support reliable alignment, no pair is guessed: the hunk is shown as missing and added lines.
Only the final modified pairs receive a grapheme-aware character comparison. The result is an atomic, source-free compact model containing row indexes, line-start arrays, and UTF-16 change ranges. The original left and right texts remain the only source of truth in the page.
The result view has fixed-height, non-wrapping rows and creates DOM only for the visible window: at most 200 rows per pane and 8,000 nodes across both panes. Very dense long lines use a paged preview. If exact character decoration must be simplified, diffvoid displays Detailed rendering reduced for performance; this never changes the text returned by Copy L/R.
Safe practical limits are 25,000 lines, 2,000,000 characters per side, 100,000 characters per line, and shared bounds for line diffing, alignment, character diffing, compact ranges, and rendering. Input outside those bounds receives a clear warning instead of unbounded browser work.
All computation happens client-side using JavaScript. Compared text may pass between the page and its in-browser Worker, but there is no backend processing and no network transmission of that text.
Detected Invisible Characters
- Zero-width space (U+200B)
- Zero-width non-joiner (U+200C)
- Zero-width joiner (U+200D)
- Non-breaking space (U+00A0)
- Hair space, thin space, en space, em space (U+200A, U+2009, U+2002, U+2003)
- Soft hyphen (U+00AD)
- BOM / zero-width no-break space (U+FEFF)
- And many more Unicode whitespace characters
Detected Confusable Characters
Confusable characters are visible letters from another script that can look like ordinary Latin letters.
diffvoid marks common Greek and Cyrillic lookalikes, such as Cyrillic А (U+0410) that looks like
Latin A, with a dotted underline and a tooltip.
Invisible characters are hidden or spacing-related. Confusable characters are visible, but easy to misread in code, domains, copied text, and identifiers.
How to Read the Diff
- Matching lines: No background highlight - text is identical.
- Modified lines: Red background with precise red character ranges when the detail budget permits.
- Added or missing lines: The source line is highlighted on one side and aligned with a highlighted empty gap on the other.
- Difference counter: Counts changed visual rows: modified, added, and missing rows.
- Invisible characters: Shown as symbols like
|,[ZWSP], or red boxes for spaces in diffs. - Confusable characters: Shown with a dotted underline, a small marker, and a tooltip that names the actual Unicode character.
- Reduced long-line preview: Previous/Next controls move between bounded views around changes; preview ellipses are not part of the source text.
- Copy L/R: Copies the exact original side. Clean L/R appears when invisible characters are detected and returns a normalized version instead.
Open Source
diffvoid.com is open source. You can inspect the code, verify the privacy claims, or contribute:
Contact
Created by Timo Heimonen
Email: timo.heimonen@proton.me