Polyatic Text Diff Checker

Text Diff Checker

Paste two versions of any text and see exactly which lines were added, removed or left unchanged — with the changed words highlighted inside each edited line, live, entirely in your browser.

Original
Changed

Files: pick or drop one per pane, up to 5 MB, decoded as UTF-8 (other encodings may mis-render); binary files are refused.

Comparison options

Comparison only — the panes always show your original text, and the .patch export always diffs the original texts, never the normalized ones.

Differences

Nothing leaves your browser. Both texts are compared on your own device with a small script you can read — there are no network requests and no analytics on this tool. Files you load are read the same way: picked or dropped files are decoded locally and never uploaded. Paste private notes, code or contracts safely; it even works offline.

What this diff tool does

A diff (short for "difference") shows what changed between two versions of a text. Paste the earlier version on the left and the newer one on the right, and the tool marks every line as unchanged, removed (red, only in the original) or added (green, only in the changed text). When a removed line is paired with the added line that replaced it, a second, word-level pass highlights the exact words that differ inside the pair, so a one-word edit in a long line jumps out immediately. It updates the instant you type — there is no button to press — so you can watch the diff shift as you edit.

Worked example: the two sample texts

The boxes above start pre-filled with a four-line original and a four-line edit. Two lines are identical, two were changed. The line diff renders six rows:

 The quick brown foxjumps over the lazy dog.+ over the lazy dog. Line three stays the same.Delete this line.+A brand new line appears.

At the line level the tool reports the old line as removed and the new line as added — one deletion plus one addition, never a guess that one "turned into" the other. But because that removed/added pair sits together, the word-level pass then marks exactly "jumps" in the red line and "leaps" in the green line with a stronger highlight, while over the lazy dog. stays plain — you see both the honest line-level story and the precise word that changed. There are 2 added, 2 removed and 2 unchanged lines, so the meter reads +2 −2, 67% changed (four changed lines out of six total). Edit either box and the rows re-flow live.

How the comparison works

Under the hood the tool computes the longest common subsequence (LCS) of the two texts, line by line. The LCS is the longest ordered run of lines that appears in both versions, even if other lines are inserted between them. Those shared lines become the "unchanged" anchors; everything left over in the original is a deletion, and everything left over in the new version is an addition. This is the same classic algorithm behind the Unix diff command and version-control tools like Git, implemented here from scratch in a few dozen lines of plain JavaScript with no libraries.

Line vs word vs character diff

Diffs come at different granularities, and the right one depends on what you are checking:

GranularityComparesBest forAn edited line shows as
Line (this tool's base)Whole linesCode, config, CSV, logs, paragraphsOne removed line + one added line
Word (this tool, inside changed pairs)Words within a lineProofreading a sentenceOnly the changed words highlighted
CharacterSingle charactersSpotting a one-letter typoThe exact letters that differ

This tool is line-level first, so when a single word changes inside a long line the whole line is still reported as removed-and-added — that keeps the counts and the exported diff predictable, and for code or config the "which line" answer is usually what you need. On top of that, each removed line that pairs with an added line gets a word-level pass that highlights only the tokens that actually differ. It does not go down to single characters: a one-letter typo highlights its whole word.

Comparison options: ignoring whitespace and case

Three independent toggles under the input boxes loosen the comparison without touching your text: ignore leading & trailing whitespace treats "foo " and "foo" as the same line (the classic trailing-space false alarm); collapse internal whitespace runs treats a  b and a b as equal, which absorbs re-indentation and tab-vs-spaces churn inside a line; ignore case treats Hello and hello as equal. They only change the keys lines are matched by — the panes and the highlighted rows always display your original bytes, and when a toggle makes two differently-spelled lines match, the unchanged row shows the original (left) version.

The .patch export is deliberately exempt: it always diffs the original texts, never the normalized ones. A patch built from normalized text would silently rewrite whitespace or casing when applied, so the export ignores the toggles entirely — what you download replays your real bytes.

The word-level pass tokenizes each paired line by splitting on whitespace while keeping the separators as tokens, so a  b becomes three tokens: a, the two-space run, and b. Because no characters are thrown away, stitching the unchanged + removed tokens back together reproduces the old line byte-for-byte, and unchanged + added tokens reproduce the new line — the highlights can never misplace a boundary. A changed separator (say two spaces becoming one) is honestly marked as its own tiny removed/added pair.

Comparing files, not just pastes

Each pane has a Load file… button, and you can also drag a file straight onto either text box. Loading a file does nothing exotic: its text simply lands in the same box that pasting fills, and the identical line-and-word diff runs — so you can load a file on one side and paste on the other, or hand-edit a loaded file and watch the diff update. The file is read and decoded entirely on your device; nothing is uploaded.

Three deliberate, stated limits keep this honest. First, files are decoded as UTF-8 — today's default for source code, JSON, HTML and most exports. There is no encoding auto-detection (guessing silently is how tools corrupt text), so a Latin-1 or UTF-16 file may render accents as garbage; re-save it as UTF-8 first. Second, files over 5 MB are refused whole with a message — never silently truncated, because a diff of a truncated file would lie about deletions at the end. Third, a file whose first 8 KiB contains a NUL byte (0x00) is treated as binary and refused: real text virtually never contains NUL (the same heuristic git uses), and line-diffing a JPEG or ZIP would just render mojibake. A PDF also counts as binary here — its text is wrapped in a compressed binary container, so extract the text first.

Reading the summary and copying a unified diff

The meter shows a compact summary such as +2 −2, 67% changed: lines added, lines removed, and (added + removed) ÷ total distinct lines as a percentage. In Inline diff mode the Copy diff button copies a plain block — added lines prefixed with , removed lines with and unchanged lines with two spaces — ready to paste into an email, a ticket or a chat where a human just needs to read it.

Exporting a real .patch file

Switch the result to Unified .patch mode to get a genuine, machine-applicable diff — the same format git diff and diff -u produce. It emits --- a/… and +++ b/… file headers, then one or more @@ -l,s +l,s @@ hunk headers whose 1-based line numbers and lengths locate each change, with a few lines of unchanged context on either side. You can set the two filename labels (defaulting to a and b), choose how many context lines surround each change (default 3; changes closer together than twice that merge into one hunk), then Copy patch or Download .patch to save the text as a file. Feed it to git apply or patch -p1 to replay the edit on another copy of the file. If a version lacks a trailing newline the output carries the standard \ No newline at end of file marker, so the newline state round-trips exactly; when the two texts are identical the patch is empty.

Line endings and whitespace pitfalls

Before comparing, both texts are normalised so Windows (\r\n, CRLF) and classic-Mac (\r, CR) line endings are treated identically to Unix (\n, LF). Without that step, the same paragraph copied from a Windows editor would show as entirely different from its Linux twin purely because of invisible carriage returns — the single most common "everything looks changed but nothing did" surprise. By default, every other kind of whitespace is compared exactly: a trailing space, a tab-vs-spaces indent change, or a blank line added at the end all count as a different line, which is what you want when reviewing code or config. When it is not what you want — say a document was reformatted but not really edited — switch on the ignore-whitespace toggles above and those differences drop out of the comparison while remaining visible (and exportable) in your original text.

Common mistakes

  • Blaming line endings. If two "identical" files show as fully different in other tools, it is usually CRLF vs LF — this tool already normalises that away.
  • Expecting character-level highlights. A one-letter typo highlights its whole word, not the single letter; word tokens are the finest grain here.
  • Trailing whitespace. A stray space at the end of a line makes it "different" even though it looks the same on screen — turn on the ignore-whitespace toggle when that noise is not what you are reviewing.
  • Expecting the toggles to change the export. The .patch is built from your original texts on purpose; ignore-options never leak into it.
  • Treating it as a merge tool. A diff shows differences; it does not combine the two versions for you.

Honest limits

The word-level highlight only appears on paired lines — the first removed line in a changed block pairs with the first added line, the second with the second, and so on. If three lines were deleted and one very different line inserted, the leftover deletions render plain, and a pairing of genuinely unrelated lines can highlight most of both — the pairing is positional, not semantic. There is no character-level diff (a one-letter typo highlights its whole word) and no three-way merge. For very large inputs (tens of thousands of lines) the LCS table grows with the product of the two line counts, so extremely long documents can get slow; for everyday texts it is instant. Everything runs in your browser: the page loads no third-party scripts and makes no network calls, so the two texts you paste stay on your device and are gone when you close the tab — safe for unreleased copy, private contracts, credentials in a config file or proprietary source.