Text Diff Checker
Comparing two versions of anything by eye is unreliable past about ten lines. A diff makes the changes explicit, and understanding how line-based diffing works explains both why it is so useful and why it sometimes produces output that looks nothing like the change you made.
How to use it
- Paste the original text on the left and the modified text on the right.
- A unified diff is computed in the page, with plus and minus prefixes.
- Nothing is transmitted, which matters for proprietary code and contracts.
How line diffing works
The algorithm finds the longest common subsequence of lines between the two versions, meaning the largest set of lines appearing in the same relative order in both. Those are the unchanged lines. Everything in the first version but not in that subsequence is a deletion, and everything in the second is an addition.
The consequence worth internalising is that a diff has no concept of modification. A changed line is represented as a deletion followed by an addition, because line-level comparison is exact: a line either matches or it does not.
It also has no concept of movement. Relocating a function from the top of a file to the bottom appears as a large deletion and an identical large addition, with no indication that they are the same content. Some tools detect moves as a post-processing step; the underlying algorithm does not.
Where the noise comes from
A diff that reports every line as changed almost always has one of three causes, none of which is a real content change.
In order of frequency:
- Line endings. Windows uses carriage return plus line feed, Unix uses line feed alone. A file that has passed through both is entirely different at the byte level, so every line differs. This is what .gitattributes and editor configuration exist to prevent.
- Trailing whitespace. Invisible, and enough to make two lines unequal. An editor that strips it on save will rewrite every line of a file that had it.
- Indentation changes. Converting tabs to spaces, or reformatting with a different tool, changes every indented line while changing nothing that matters.
Line diffs versus word diffs
Line granularity suits code, where lines are meaningful units and a change usually affects whole lines. It suits prose badly, because a paragraph is often one very long line, so correcting a single word marks the entire paragraph as changed.
Word-level and character-level diffs exist for that case and are what document comparison tools use. They are more expensive to compute and produce output that is harder to read for code, which is why the two granularities coexist rather than one replacing the other.
For prose, a practical middle ground is to hard-wrap at sentence boundaries. One sentence per line makes a line diff behave like a sentence diff, and it is why some documentation projects adopt the convention.
Why comparing locally matters
The things people most often need to diff are the things they should least want to upload: two versions of a contract, a configuration file containing credentials, proprietary source code, or a data export before and after a migration.
Comparison here happens in the page. Neither version is transmitted, and you can confirm that in the network tab.
At a glance
| Granularity | Line level |
|---|---|
| Output | Unified diff with plus and minus prefixes |
| Whitespace | Significant, differences are reported |
| Transmitted | Nothing |
Frequently asked questions
Why is every line showing as changed?
Almost certainly line endings. One version uses CRLF and the other LF, which makes every line differ at the byte level. Trailing whitespace and indentation changes do the same thing.
Why is a moved block shown as a delete and an add?
The algorithm matches lines in order and has no concept of movement. Relocated content is a deletion in one place and an identical addition in another.
Can it diff individual words?
No, comparison is line based. For prose, hard-wrapping one sentence per line makes a line diff behave much like a sentence diff.
Is my text uploaded?
No. Both versions stay in the page. That is the point for contracts, configuration, and proprietary code.
Read more
Working with text — Diffs cannot see movement, regular expressions cannot count, and case conversion is not locale-independent.