Skip to content

kingxiaozhe/diff-lens

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DiffLens — Private Text Compare

CI MIT License

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.

DiffLens private text comparison

Install

  1. Download and extract the latest ZIP from Releases, or clone this repository.
  2. Open chrome://extensions and enable Developer mode.
  3. Choose Load unpacked and select the extracted directory.
  4. Click the DiffLens toolbar icon to open the full-page comparison workbench.

Features

  • 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 ```diff block 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.

Package it for the store

node package.mjsdifflens-<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.

Load it locally (for testing)

  1. chrome://extensions → enable Developer mode.
  2. Load unpacked → select this folder.
  3. 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).

Develop / test

  • 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 exactly storage + 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.

About

Private in-browser text diff with move detection, JSON normalization, local files, history, and patch export.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages