Text Diff
Compare two blocks of text line by line. Added and removed lines are marked and counted, with ignore-case and ignore-whitespace options.
5 lines
6 lines
changes = lines − LCS(a, b) · identical prefix and suffix stripped before the O(n×m) table
Line level only: a line changed by one character is one removal plus one addition, with nothing highlighted inside the line. The first 2,000 lines of each side are compared.
How it works
Paste the original into the left box and the changed version into the right. The diff recomputes on every keystroke.
Read the markers. A leading - is a line only the original has, + is a line only the changed side has, and a space is a line both share. The background tint repeats the same three states, so the marker is never the only signal.
Turn on "Ignore leading and trailing whitespace" when the indentation moved but the content did not, and "Ignore case" when only capitalisation is in question. Both change what counts as a match; every line is still shown exactly as it was typed.
Switch on "Only changed lines" to drop the shared context on a long file, and use Copy diff to take the marked output with you.
Everything runs in this tab. The text is never uploaded, and nothing is saved between visits.
How the comparison works
The two sides are split into lines and matched with a longest common subsequence, computed by dynamic programming. Every line in the LCS is unchanged; every line of the original that is not in it was removed; every line of the changed side that is not in it was added. That is what separates this from comparing line 1 to line 1, line 2 to line 2 and so on — under a zip comparison, inserting a single line at the top reports every line below it as changed, because each one has shifted by one position. The table is O(n x m) in the two line counts, so the identical prefix and suffix are stripped first and the table is built only over the part that actually differs. Inputs are capped at 2,000 lines per side, which bounds the worst case at roughly four million cells.
LCS(i, j) = 1 + LCS(i+1, j+1) if a[i] = b[j], else max(LCS(i+1, j), LCS(i, j+1))
Use cases
Compare two config files
Paste an nginx block, a .env, a Dockerfile or a YAML manifest into each side and read which directives moved. Line endings are normalised first, so a file saved on Windows and the same file saved on Linux do not report every line as changed over an invisible carriage return.
See what a formatter changed
Run Prettier, gofmt or Black, paste the before and after, then toggle "Ignore leading and trailing whitespace". If the diff empties out under the toggle, the tool only reindented; if lines remain, it rewrote something and those lines are the ones to read.
Diff two JSON payloads
This is a text diff, not a structural one — it compares lines, so reordered keys read as a removal plus an addition and a whole payload on one line reads as one changed line. Pretty-print both sides with the same formatter first and the comparison becomes useful; for key-level semantics you want a JSON-aware differ.
Compare two lists
Dependency lists, email exports, feature flags, SKUs. One item per line on each side and the additions and removals fall out directly. Turn on "Ignore case" when the two lists came from systems that disagree about capitalisation.
Check what a model rewrote
Paste your original text on the left and the returned version on the right to see exactly which lines an assistant touched, rather than rereading the whole answer looking for the edit.
Compare two log excerpts
A working run and a failing run side by side. The unchanged lines are the shared path and the marked ones are where the two diverged, which is usually the first + or - in the output.
Proof two drafts of the same copy
Marketing copy, release notes, a licence, a policy. Keep one sentence per line and the diff reports sentence-level edits; keep whole paragraphs on one line and it reports the paragraph as rewritten, because the unit of comparison is the line.
Verify a paste survived the trip
A key, a certificate body or a long token pasted through a chat client, a ticket field or a spreadsheet cell. Diffing it against the source shows whether a line was wrapped, trimmed or silently smart-quoted along the way.
Questions
- Is anything uploaded?
- No. The comparison runs in this tab. There is no upload, no request, no analytics, and nothing is written to storage — reload the page and both boxes are back to their defaults.
- How does it decide which lines match?
- It computes a longest common subsequence over the lines with the standard dynamic-programming table. That matters: comparing line 1 to line 1, line 2 to line 2 and so on would report every line after a single insertion as changed, because each one has shifted position.
- Is there a word-level or character-level diff?
- No. This is a line diff only. A line that changed by one character is reported as one removal and one addition, with no highlight inside the line. That is the honest limit of the tool and the main thing it does not do.
- How large an input does it take?
- The first 2,000 lines of each side. The table is O(n x m) in the two line counts, so two entirely different 2,000-line texts is the slow case; the identical prefix and suffix are stripped before the table is built, which is why a small edit in a large file stays instant. When the cap is hit, the tool says so above the output rather than quietly comparing a fragment.
- What exactly does "Ignore leading and trailing whitespace" do?
- It trims each line at both ends before comparing, so indentation and trailing spaces stop counting as differences. Whitespace inside a line still counts — two spaces between words is not the same line as one. The lines are always displayed as typed; only the matching changes.
- Does it handle Windows line endings?
- Yes. CRLF and lone CR are normalised to LF before the text is split, so the same content saved on Windows and on Linux compares as identical instead of as a complete rewrite. Note the flip side: this tool will not tell you that the line endings differ.
- Why is there a blank line at the end of my diff?
- A trailing newline produces an empty final line, and that is a real difference between a file that ends with a newline and one that does not. If only one side has it, you will see a single empty added or removed line at the bottom.
More tools
One of 18 free tools here. They come out of building utility apps for macOS, iOS and the browser — all of it by one person.
See the apps