What line-granular actually costs you
The comparison splits both texts into lines, finds the longest sequence of lines that appears in both in the same order — the longest common subsequence — and marks everything outside that sequence as removed from A or added to B. This is the same algorithm behind git diff and most document comparison tools, and its granularity is the line.
That has one consequence worth internalising: there is no such thing as a changed line here. Fix a typo in a 200-character line and you get that entire line marked removed and an almost identical line marked added, with nothing pointing at the character that moved. The tool cannot show you a word-level or character-level highlight inside the pair, so on a densely edited paragraph you end up reading both versions side by side anyway.
The same limitation produces the other surprise. A moved block is a deletion plus an insertion. Cut a function from the top of a file and paste it at the bottom and the diff reports every one of its lines as removed and every one as added, with a change percentage that suggests you rewrote the file. Reordering clauses in a contract behaves identically. Nothing is wrong — LCS has no concept of a move, only of presence and order — but the change count overstates the work by roughly double whenever a move is involved.
Ambiguity when the same line repeats
LCS guarantees a minimal edit script but not a unique one. When several different alignments are equally minimal, the algorithm picks one by a fixed tiebreak rule, and that choice is not always the one a human would make. Text with many identical lines makes this visible: blank lines, lines containing only a closing brace, repeated table separators, a list of similar bullet points. You will sometimes see the diff attach an addition to a different repeated line than the one you edited, so the coloured region is offset by a line or two from where the real change is. The set of added and removed lines is still correct; only the pairing is arbitrary.
When to switch the ignore options on
Whitespace ignoring trims each line and collapses internal runs of spaces to one before comparing, while still displaying the original line. Turn it on for code that was reindented, for config files where tabs and spaces got mixed, and for prose that went through a word processor and came back with different spacing. Note that with it on, a line of nothing but spaces and a genuinely blank line compare as equal.
Ignoring case is for identifiers, headings and anything where a capitalisation change is noise. Be careful with it on code where case is significant, since it will hide a rename from userId to userid entirely.
Both options affect comparison only. What you see in the table is always the original text, so you can turn whitespace ignoring on to find the real changes, then turn it off to see whether the indentation change was intentional.
Characters that survive the ignore options
Line endings are normalised on the way in, so a file saved with CRLF and one saved with LF do not read as entirely different. What does not get normalised is anything Unicode considers a distinct character even though it looks like a space or a quote: a no-break space at U+00A0, an ideographic space at U+3000, a zero-width space at U+200B, a curly apostrophe versus a straight one, or a letter written as a base plus a combining accent instead of its precomposed form. All of those produce a difference that whitespace ignoring will not remove, because the tool does not treat them as whitespace or as equivalent characters. If two lines look identical and keep coming up as changed, that is the place to look — and a text editor that can show invisible characters will find it in seconds.
Size, and what to do about long paragraphs
The comparison table is quadratic in the number of differing lines, so the tool refuses when the two differing regions multiply out past six million cells, around 2,400 by 2,500 lines. Identical text at the start and end is trimmed off before that check, which means two large but similar files usually compare fine and two large dissimilar ones do not.
The related practical problem is documents where each paragraph is one long unbroken line. With no line breaks the smallest unit the tool can see is the whole paragraph, so a two-word edit reports the entire paragraph as replaced. Before comparing a document like that, put each sentence on its own line in both versions — a search and replace of ". " with ".\n" gets most of the way there — and the diff becomes precise enough to be useful. Both texts stay in the browser throughout; nothing is transmitted, which is the reason this is a reasonable place to put a contract redline or a production config file.
Questions people ask
Can it highlight which characters changed within a line?
No. The comparison unit is the line, so an edited line appears as a removed line and an added line with no indication of which characters differ. You have to read the pair. This is a deliberate limit rather than a missing feature — word-level and character-level diffs need a second pass inside each changed pair and produce noisy results on prose, where a small wording change can reshuffle a whole clause. If precision matters, break the text into shorter lines before comparing.
I moved a section and it says the whole thing changed.
That is expected. The algorithm knows only which lines are present and in what order, so a block that moved is simply absent from its old position and present in a new one — reported as a full deletion plus a full insertion. The change percentage roughly doubles for the moved region as a result. No line-based diff tool detects moves without a separate move-detection pass, and this one does not have one.
Two lines look identical but show as different.
Almost always an invisible character. The usual suspects are a no-break space (U+00A0) pasted from a web page, a zero-width space (U+200B), an ideographic space (U+3000), a curly apostrophe where the other line has a straight one, or an accented letter stored as a base letter plus a combining mark in one version and as a single precomposed character in the other. None of those are affected by the ignore-whitespace option, since the tool does not classify them as whitespace. Turn on invisible characters in a text editor to find it.
Is there a size limit?
Yes. Matching leading and trailing lines are trimmed first, then the two differing regions are compared with a table whose size is their product. If that product exceeds six million cells — about 2,400 by 2,500 lines of genuine difference — the tool declines and says so instead of allocating an enormous array. Large files that are mostly identical compare without trouble because the trimming removes nearly all of the work.
Does the text get uploaded to compare it?
No. Both blocks stay in the page and the entire comparison runs in JavaScript in your browser. There is no request to any server, nothing is stored, and closing the tab discards it. That is the point of doing it here rather than in a web service, since the things people most often need to diff — contracts, credentials-bearing config, unreleased copy — are exactly the things that should not be pasted into someone else’s backend.