What a diff actually computes
Comparing two texts is not a matter of walking both from the top and reporting the first place they stop matching — insert one line at the start of a file and every line after it moves down by one. What a diff looks for instead is the longest sequence of lines the two texts still share, in order; everything in that sequence is unchanged, and everything else is an insertion or a deletion.
the quick brown fox vs the quick red fox → one changed row, with only brown and red tinted
Two operations, then: insert and delete. A rewritten line is a deletion and an insertion that happen to land in the same place, so this tool pairs them back into one changed row and runs the same comparison again inside it, over words or characters — and that inner pass is the difference between reading a diff and hunting through one. Nothing here reaches the network, which is why a contract draft or a production config is as safe to paste as a code snippet.
Every control, and when to reach for it
Five controls, and each one changes a different thing. Two change what counts as a difference, one changes how closely a difference is examined, and two change how the result is laid out.
| Control | What it does | Reach for it when |
|---|---|---|
| View | Puts the two texts in facing columns, or in one column with removals and additions marked. | You are reading on a phone, or you want something that reads like a patch. |
| Diff precision | Sets what a changed line is compared by inside itself: nothing, whole words, or single characters. | A line changed by one character and you want to see which, or the highlighting is too noisy and you want it off. |
| Ignore case | Compares lines and words with case folded away. | One side has been through a formatter, or you are comparing values from case-insensitive systems. |
| Ignore whitespace | Folds every run of spaces and tabs into one and trims both ends before comparing. | Indentation changed, or one side was re-wrapped, and you only care about the content. |
| Hide unchanged lines | Keeps a few lines either side of every change and folds the rest into a marker saying how many are hidden. | Two long files differ in three places and you do not want to scroll past the rest. |
The two ignore options are the ones worth being careful with, because they make differences disappear. A line that matches only after case or whitespace was folded away is still marked, quietly, on the row itself and counted in the line under the boxes — so "no differences" never means "no differences, as long as you do not look too closely".
They apply inside a line as well as between lines. With case ignored, a word that differs only in case is not highlighted either; anything else would be a comparison that disagrees with itself depending on how far you zoom in.
Precision is the one control that cannot change the verdict. Line, word or character, the same lines are added, removed and rewritten — all it changes is how much of a rewritten line is tinted.
Split or unified
The split view puts the two texts in facing columns with their own line numbers, which is the layout to reach for when you want to read both versions. A changed line sits on one row with the old text on the left and the new text on the right, so your eye can move across rather than up and down.
The unified view puts everything in one column: removals first, then additions, each marked with the leading minus or plus that every patch file uses. It is narrower, which is why it is the better choice on a phone, and it is the same shape as the patch the export button hands you.
Both views fold unchanged runs the same way when you ask them to, and both let you step between changes with the arrows rather than scrolling for them.
Exporting a unified patch
Copy or download gives you a unified diff — the format git apply and patch read, with a header naming each side, one hunk per region that changed, and three lines of context around each. It is built from the same comparison on screen, so what lands on disk cannot disagree with what you were looking at.
One detail is worth knowing, because it trips people up in every diff tool. A text ending in a newline is shown here with a final blank line, because that blank line is really there. A patch describes the same thing differently: it counts one fewer line and marks any side whose last line has no ending with \ No newline at end of file. The export converts between the two, which is why the patch can have one line fewer than the screen does.
Lines that matched only because an ignore option was on are context in the patch, not changes — the patch describes what has to happen to the text, and folding case or whitespace away is a way of reading it, not an edit to make.
How big a comparison can get
Lining up two texts costs work in proportion to the size of both multiplied together, so there are limits: 200,000 characters and 5,000 lines a side, and a ceiling on the comparison itself. Identical runs at the start and end are matched off before any of that is measured, which is why two long files that differ in a few places sit well inside the limits while two entirely different ones of the same size may not.
When a limit is hit the tool says which one rather than hanging or silently truncating. The answer is usually to compare the part you care about: a section, a function, a single object out of a config.
What people compare here
Two responses from an API before and after a deployment. A config file against the one that actually shipped. Two exports of the same table. A contract draft against the version that came back from the other side. A block of generated code against the block it replaced.
It is also the fastest way to answer "are these two things the same?" for anything long enough that reading both is not an option — two keys, two long identifiers, two minified bundles. Turn precision up to character and the answer is a single tinted run.
For anything where the two sides are versions of a file you keep, a real version control system will always tell you more. This is for the two things in front of you right now, neither of which is in a repository.
