Using a Text Compare Tool, and How diff Actually Works
Spotting differences between two texts by eye is one of the things humans are worst at. A diff algorithm reframes it as finding the minimum set of edits that turns one into the other, and solves it mechanically. This tool shows the result as additions, deletions, and changes — and reading that result accurately is easier if you know what the algorithm is minimizing.
How to use it
- Paste the original on the left and the version to compare on the right.
- Changed regions are highlighted, with added and removed lines distinguished by color.
- If there are more differences than expected, check the line-ending and whitespace section below.
- For structured text like JSON or code, formatting both sides the same way before comparing makes the result far more readable.
What diff minimizes
Most diff implementations frame the task as finding the longest common subsequence (LCS): identify the longest run of content the two texts share in order, and whatever remains becomes the deletions and additions. Myers' algorithm is the standard way to compute this at practical speed, and Git uses that family by default.
That has an important consequence. The algorithm finds the answer with the fewest edits, not the answer a human would find most natural. So moving a function upward shows as 'deleted below, added above', and in code with many similar lines the block boundaries can drift so that unrelated lines get paired. This readability problem is exactly why Git offers alternatives like --patience and --histogram.
When the texts look identical but compare as different
This bites most often with text copied from the web. Strings taken from HTML frequently carry non-breaking spaces (U+00A0) or zero-width characters that render identically to ordinary spaces on screen.
| Cause | How to check | Fix |
|---|---|---|
| Line endings (CRLF vs LF) | Hex viewer, or :set list in vim | Normalize (dos2unix, .gitattributes) |
| Trailing whitespace | Search with /[ \t]+$/ | Enable trim-trailing-whitespace in your editor |
| Mixed tabs and spaces | Your editor's whitespace rendering | Run both through a formatter |
| Final newline present or absent | Compare wc -l output | Add the newline |
| Non-ASCII spaces (U+00A0 etc.) | Escape it with a Unicode converter | Replace with ordinary spaces |
| Invisible zero-width characters | Same escaping approach | Remove them |
| Unicode normalization (NFC vs NFD) | Compare after normalize() | Normalize both to one form |
Line-level versus character-level comparison
diff's default unit is the line, so changing a single character marks the whole line as removed-then-added. That's appropriate for code, but for a document where one long sentence was edited it hides where the change actually is.
So in practice you match the unit to the material. Word-level diff reads far better for prose (git diff --word-diff), while for a minified file where everything sits on one line, line-level comparison is effectively useless — there, the right move is to un-minify into multiple lines first and then compare.
Common uses
- Checking how a config file differs between production and staging
- Verifying whether an API response changed across a deploy (format both sides identically first)
- Finding keys added to or missing from a translation file
- Working out which dependencies actually changed when reviewing a package-lock.json diff
- Comparing two logs to isolate lines that only appear in the failing run
- Reviewing edits between drafts of a document
- Comparing contract or terms-of-service revisions
Comparing structured data
Comparing JSON as raw text produces piles of meaningless differences, because reordered keys or a different indent width all register as changes. To find out whether values actually differ, normalize both sides first: sort the keys, format with identical indentation, then compare. Whatever remains is a real difference.
# sort keys and emit identical formatting, then diff jq -S . a.json > a.norm.json jq -S . b.json > b.norm.json diff a.norm.json b.norm.json
Frequently Asked Questions
- Is my text sent to a server?
- No — the comparison is computed in your browser. Even so, pasting contracts or documents containing personal data into a third-party site may conflict with your organization's policy, so check first.
- Can I ignore whitespace differences?
- This tool compares exactly as given. To ignore whitespace, clean both sides beforehand or use diff -w or git diff -w on the command line. Be careful in whitespace-significant languages like Python and YAML, where ignoring it can hide a real change.
- Can it handle very large files?
- It runs in browser memory, so a few thousand lines is fine, but hundreds of thousands may slow down or freeze the tab. diff computation can scale worse than linearly, and the cost grows especially when there are many differences. For large files, prefer command-line diff or git diff.
- Why does moved code show as a deletion plus an addition?
- Standard diff has no concept of a move — only deletions and additions. Recognizing moves requires a tool that supports it: Git's --color-moved highlights moved blocks in a different color, and some code review tools offer something similar.
- Can I apply the diff as a patch?
- Applying a patch needs unified diff format. Generate it with diff -u a.txt b.txt > change.patch and apply with patch -p1 < change.patch. Inside a Git repository, git diff and git apply are safer.
- Can I compare three or more texts at once?
- This tool compares two. For a three-way comparison (a common ancestor plus two variants), use diff3, git merge-file, or your editor's 3-way merge view — that's precisely the shape you need when resolving a merge conflict.
💡 Note: When there are far more differences than expected, suspect format before content. A single line-ending mismatch marks every line as changed.