About this diff checker

A small, dependency-free tool for one job: showing exactly which lines changed between two versions of a text. No account, no upload, nothing saved between visits.

Why it exists

Comparing two versions of a file by eye is slow and error-prone, and pasting both into a general-purpose editor to eyeball the difference misses small changes — a trailing space, a duplicated line, a single word swapped inside a long paragraph. A proper diff makes the comparison exact: every line is accounted for as unchanged, added or removed, with nothing left to a reader's attention span.

This tool exists to do exactly that for plain pasted text, without needing a local install, an account, or a copy of the files on a server anywhere.

How the comparison is implemented

Both texts are split into lines, then compared with a standard longest common subsequence (LCS) algorithm: a dynamic-programming table of size (lines in A + 1) × (lines in B + 1), filled bottom-up, then walked backwards from the last cell to read off the sequence of unchanged, added and removed lines. This is the textbook technique behind line-oriented diff tools generally — there is no shortcut or heuristic substituted for it here.

  • The comparison key can differ from the displayed text. When "ignore case" or "ignore leading/trailing whitespace" is on, the algorithm compares a normalised version of each line, but the line shown in the output is always exactly what was typed.
  • A single trailing newline is not a line difference. Text ending "...foo\n" and text ending "...foo" both resolve to the same final line, which matches how most editors and version-control tools already treat a file's trailing newline.
  • Large inputs are capped, not left to hang. The DP table above is capped at four million cells. Past that, whichever side is larger gets trimmed to the first however-many lines that fit, the trimmed count is reported in a note, and the comparison still returns in well under a second rather than freezing the tab.

How it was verified

The pure diff function has no DOM dependency, so it was run directly under Node against a set of fixed cases before shipping:

Verification cases and results
CaseExpectedResult
Identical inputs0 added, 0 removedpass
Total replacement (no shared lines)Every line removed and re-addedpass
Insertion in the middle of otherwise-identical textExactly one added line, surrounding lines unchangedpass
Trailing newline present vs absent (\n, \r\n)No diff reportedpass
Ignore-case, ignore-whitespace, ignore-blank-lines optionsEach independently collapses its class of difference to zeropass
3,000 × 3,000 line input (9,000,000 cells, over the 4,000,000 cap)Truncates gracefully with a reported skip count, completes in millisecondspass
1,500-line input with one inserted line, under the capExactly one added line, no truncationpass

All cases passed. The same module is what runs in the browser — there is no separate implementation for the demo versus production.

How the site is built

  • Static HTML, one small stylesheet, two small scripts. No framework, no build step, no bundler.
  • The tool needs nothing from the network. No CDN library, no web font, no remote image; the favicon is an inline SVG data URI.
  • System font stack. Your operating system's UI font, so nothing has to download and nothing shifts as it loads.
  • Nothing you paste is transmitted. The comparison happens entirely in your browser. Opening your browser's network panel while comparing two texts shows no request being made.
  • No innerHTML anywhere in the tool. Every diff line is built with document.createElement and textContent, so pasted text that happens to look like markup is always rendered as plain characters, never parsed.
  • Dark mode follows your system setting via prefers-color-scheme.

Scope and honesty about limits

This is a line-level diff. It does not highlight which word changed inside a line, it does not detect that a block of lines moved rather than being deleted and re-added elsewhere, and it is not a merge tool — it will not combine the two texts for you. It also has no idea what format it is looking at: code, JSON, YAML and plain prose are all just lines of text to it, so it cannot validate or reformat anything.

For very large pastes, the comparison is capped at four million table cells (roughly a few thousand lines on each side, depending on how uneven the two texts are) so the tab never locks up. When that cap is hit, a note states exactly how many trailing lines on each side were left out of the comparison.