Compare two texts line by line, with exact character changes.

Both texts are read locally, including dropped files. Nothing is uploaded for comparison. How to verify this yourself.

Ready
Original 0 lines
Changed 0 lines
Diff +0 -0 ~0 =0
Unified view

How a diff algorithm decides what changed

A diff looks like a simple question — what changed? — but the answer depends on a decision you did not make: which pairs of lines are allowed to be called "the same line, edited" versus "a line removed and a different line added". This page shows that decision, both at the line level and inside each changed line. Everything runs in the tab; both texts stay on your device.

A diff is an edit script, and LCS picks the cheapest one

The algorithm here is built on the longest common subsequence. Given the two lists of lines, it finds the largest set of lines that appear in both, in the same order, and declares everything outside that set to be changed. That is not an arbitrary choice: the longest common subsequence is the largest possible set of unchanged lines, so the number of edits left over is the smallest possible. A diff tool is, in effect, solving "how few edits turn the left file into the right one".

The word subsequence is doing real work, and it explains most surprising output. A subsequence does not have to be contiguous, so moved blocks can be matched if their order survives, but a block moved past another block cannot. The algorithm has no notion of "moved" — moving a function from the top of a file to the bottom is reported as a deletion plus an insertion, which is correct as an edit script and unhelpful as a review comment. Duplicate lines are the other classic wrinkle: if a file contains several identical closing lines, they are interchangeable as far as the algorithm is concerned, and it will match whichever copy keeps the alignment cheapest, which is not always the copy a human would have paired.

Why a character-level second pass matters

Line-level output has a blind spot that shows up constantly with configuration files. Two lines can be almost identical — the same key, the same formatting, one digit different — and a line diff can only tell you that the whole line changed. You then have to scan both lines character by character in your head, which is exactly the work you opened a diff tool to avoid.

So each replaced line gets a second pass. The tool strips the characters the two lines share at the start and at the end, then runs the same subsequence logic on the small region that is left, and marks the characters that did not match. A port number going from 8080 to 8090 highlights two digits, not the whole line. That contrast between a wall of red and two orange digits is the difference between a tool you trust and one you re-check by hand.

The character pass runs per line, so it is capped twice. A line longer than a couple of thousand characters skips it entirely, and inside a shorter line the region that differs is still bounded. This is aimed squarely at minified JSON, where an entire API response is a single line of tens of thousands of characters; a naive character comparison across two such lines is quadratic and will lock up a tab.

Options change what counts as equal

The ignore switches do not change the algorithm, they change the notion of equality that feeds it. With "Ignore whitespace", every run of spaces and tabs collapses to a single space and the ends are trimmed before lines are compared, so a file that was reformatted compares as identical. With "Ignore case", comparison is done on lower-cased text. Both make more lines count as unchanged, which shortens the edit script — and that is the point, because a whitespace-only difference is noise you asked to remove.

"Ignore blank lines" is different in one respect worth knowing: blank lines are removed only for the purpose of matching, but the line numbers shown are still the numbers in your original files. That matters when you want to jump to the real location of a change rather than to a position in a filtered copy.

Verifying that the comparison is local

Open your browser's developer tools, switch to the Network panel, clear it, and compare two files. Nothing carrying their contents is sent. Then turn off the network and compare again — it still works, because the whole computation lives in the page you already loaded. The privacy policy lists every script the site runs and what it can see.

Common questions

Are my files uploaded to compare them?

No. Both texts are read locally — by paste, by the file picker, or by dragging a file onto an input panel — and the comparison runs in the page. You can confirm it by clearing your network panel and comparing two large files: no request is made. This matters when the files are configuration dumps or logs that carry credentials.

Why does the tool highlight the whole line instead of the characters I changed?

It usually highlights the characters. Every replaced line gets a second, character-level pass, and the differing characters are wrapped in a stronger highlight so you can see the exact edit. The exception is a line longer than 2000 characters, where the character pass is skipped on purpose: a single-line minified document can be tens of thousands of characters, and a character comparison across two of them is what makes naive diff pages freeze.

What does the side-by-side view do on a phone?

It is not offered there. On narrow screens the result is always the unified view, where each changed line is shown as a removed line followed by an added line. Two columns of text at phone width are unreadable, so the toggle is hidden below 768 pixels and reappears when the viewport is wide enough to give each column a usable width.

Is there a file size limit?

There is no paywall and no hard upload limit. Above about 3,000 lines on one side the page stops re-comparing on every keystroke and waits for you to press Compare, because a full line diff on that much text makes typing feel broken. Very large inputs also fall back to a coarser comparison rather than allocating an enormous table and hanging the tab.

Does "Ignore whitespace" also ignore indentation?

It ignores every run of whitespace: leading indentation, trailing spaces, and internal runs all normalise to a single space before comparison. That is what you want when a file was reformatted. It does not make "a b" equal to "ab", because removing the space entirely would change the meaning of the line rather than its layout.