A fast, 100% private text diff that lives in your browser. Paste or right-click two pieces of text and instantly see a clear, readable difference — nothing uploaded, no account, no ads, no paywall.
Unlike diffchecker.com and friends, DiffLens never sends your text anywhere: it
requests no host permissions and makes no network calls (only storage +
contextMenus). Built for comparing prose, not just code — word-wrap is on by
default and changes are highlighted down to the word.
- Download and extract the latest ZIP from Releases, or clone this repository.
- Open
chrome://extensionsand enable Developer mode. - Choose Load unpacked and select the extracted directory.
- Click the DiffLens toolbar icon to open the full-page comparison workbench.
- Click the toolbar icon → opens a full browser tab (no cramped popup that vanishes when you click away). Re-clicking focuses the tab it already opened.
- A workbench layout — a slim utility bar, the two input panes, a dedicated options row, the diff at full width, and a status bar carrying the counts and difference-navigation. Every compare option stays visible at once; nothing is buried in a menu.
- Two-pane compare with a live diff — unified, side-by-side (split), or inline view (one merged column: the original text with edits marked in place).
- Word- or character-level highlighting inside changed lines (toggle).
- Move detection — a distinctive line deleted in one place and re-added in another is flagged as moved (with a "moved from/to line N" badge) instead of an unrelated delete + add, and counted separately in the stats.
- Format JSON — one click parses, sorts keys & pretty-prints both sides, so JSON that differs only in key order or formatting compares as identical and real differences stand out (a structural compare).
- Compare local files — drag a file onto a pane, or "open file…". Read with FileReader, so they never leave your machine (no upload, no permissions needed).
- Right-click → "set as Text A/B" to capture selections from any page (even across two tabs), then compare.
- Jump between differences (↑/↓ or Alt+↑/↓) with a hunk counter.
- A change-marker rail beside the result — one colored pip per change (green added / red removed / amber modified) at its position in the document; click a pip to jump straight there. Great for long documents.
- Show whitespace — reveal spaces (·), tabs (→) and trailing whitespace.
- Unimportant differences — when you ignore whitespace/case, those diffs are dimmed (still visible), not silently dropped (Beyond Compare's 3-state model).
- Export the diff — copy as plain text, copy/download a standard **unified diff
(
.patch,git apply-ready), or copy as Markdown (a fenced```diffblock that renders red/green on GitHub). - Synchronized scrolling — the two input panes scroll-lock so the same region of A and B always lines up while you read long text.
- Comparison history — save a snapshot of the current A/B with one click and restore (or delete) it later from the History menu. Stored locally only.
- Ignore whitespace / ignore blank lines / ignore case; word-wrap; swap A↔B; copy result.
- Collapse unchanged (optional) — on large, mostly-identical inputs, fold long runs of unchanged lines into a band you can click to expand (off by default, so prose still shows in full).
- Real source line numbers, preserved even when blank lines are ignored.
- Panes, view, and options persist between opens.
- Light & dark, follows your system theme.
node package.mjs → difflens-<version>-upload.zip (16 files, ~39 KB).
The zip is derived, not curated: it starts at manifest.json and takes the
closure of every local file it and compare.html reference. Wire a new script
into the page and it ships; leave a note in icons/ and it doesn't, because
nothing points at it. Zipping the folder by hand would ship ~3 MB of design
drafts, specs, screenshots and tests — none of which the extension runs.
chrome://extensions→ enable Developer mode.- Load unpacked → select this folder.
- Click the toolbar icon to open the compare tab. To pull text off a page, right-click a selection → "set as Text A/B" (an open tab updates live).
- Engine + export unit tests (no deps):
node tests/diff-test.mjs - History helper unit tests (no deps):
node tests/history-test.mjs - End-to-end UI smoke (headless Chromium via Playwright):
node tests/smoke.mjs— drives the real UI and enforces the privacy invariant: the manifest must grant exactlystorage+contextMenus, and no source file may reach the network. Needs Playwright (npm i -g playwright && npx playwright install chromium); without it the script exits 2 rather than failing. The two unit suites stay dependency-free and must pass regardless.
Code layout: diff.js (engine) · history.js (history model) · five ui-*.js
modules (render / nav / export / history UI / file loading) · app.js (orchestration
only — wiring, state, bindings). See docs/ARCHITECTURE.md for design decisions
and known limitations.
100% local — your text never leaves your browser.
