Toolkit
All tools
Compare two versions · Free

Text Diff Checker

Paste an old version and a new one and see exactly what was added, removed, and changed: line by line or word by word, with whitespace and case controls, aligned and unified views, and a unified patch you can copy straight into a review.

Compared in your browser · Nothing uploaded

Text comparison workspace

Both panes are empty. Paste a version into each side to compare them.

Compare desk

Paste the two versions

Old on the left, new on the right. Both stay in this tab: no upload, no request, no copy kept anywhere.

0 lines · 0 words · 0 chars
0 lines · 0 words · 0 chars
Detail inside a changed line
Pair lines when they are

A removed line and an added line are only compared inside each other above 0.30 shared characters.

Treat as equal

These change what counts as equal, never what is shown. Every character on screen and in the copied patch is exactly the one you pasted.

No differences
n/a

Paste a version into each pane and the comparison appears here.

Lines added
0
Lines removed
0
Lines changed
0
Lines untouched
0
Words added
0
Words removed
0
Chars added
0
Chars removed
0
The comparison

Side by side, in matched gutters

Additions carry a plus and an underline, deletions a minus and a strikethrough, so the result survives being printed in black and white or read without colour.

Both panes are empty. Paste an earlier version on the left and a newer one on the right, or press Load a sample to see a pair of release notes carrying every kind of change at once: three reworded lines, one rewritten line, a new line, a new blank line, and a trailing space you would never spot by eye until you turn on Show invisibles.

Unified patch

The same comparison, as a patch

Real hunk headers, context lines either side, and hunks merged when they sit close together. These are the conventions git and GNU diff use.

A unified patch appears here as soon as there is something to describe.

A moved block appears twice

The edit script has two verbs, delete and insert; there is no move. Relocating a paragraph is spelled as its disappearance here and its arrival there, which is why one action produces two blocks of colour.

Shortest is not unique

Comparing “a b c” with “a c b” has two equally short answers, and every tool picks one by convention. When a diff blames a line you did not touch, it has usually chosen a different account of the same change.

Whitespace is sometimes the whole point

Ignoring spacing is right for prose and reformatted code. It is wrong for Python, YAML, and Makefiles, where indentation and a literal tab are syntax. There, a whitespace-only change is the change.

Both texts stay in this tab. The comparison is plain JavaScript running on your own machine: nothing is uploaded, no request is made, and no copy is stored anywhere, so a contract, a draft, or a config file with a key in it is as safe here as it is in your editor. Each side takes up to 200,000 characters or 10,000 lines; past the search limits a region is reported as one block replaced by another and the page says so rather than pretending the answer is minimal.

How it works

Two texts, and the cheapest story that connects them.

A diff is not a list of differences; it is the shortest set of deletions and insertions that turns the first text into the second. That is a real distinction. It explains why a moved paragraph appears twice, why an edited line is technically a removal standing next to an addition, and why two different tools can disagree about the same change and both be right. This page runs Myers' algorithm over the lines, refines each changed pair inside itself, and shows its working, including the moments it had to settle for a coarser answer.

  1. 01

    Paste both versions, one either side

    The old version goes left, the new one right. Neither is uploaded: the comparison runs entirely inside this tab, so a contract, a draft, or an API key in a config file never leaves your machine. Got them the wrong way round? One button swaps the sides and the reading flips with them.

  2. 02

    Decide what counts as a difference

    Whitespace, letter case, and blank lines are only differences if you say they are. Turn any of them off and the comparison changes; the text on screen does not, because the options only ever affect what is treated as equal. Granularity decides how a changed line is broken up: whole line, word by word, or character by character.

  3. 03

    Read it side by side, or take the patch

    The aligned view puts the two versions in matched gutters with line numbers; the unified view stacks them the way a code review does. Either way, additions carry a plus and an underline, deletions a minus and a strikethrough, so the result survives being printed in black and white. The unified patch copies out with real hunk headers.

Built for drafts, contracts, configs, and code review

Minimal edit scripts, word-level detail, and a patch that actually applies.

A shortest edit script, not a first guess

The comparison is Myers' algorithm, which finds a script of minimum length rather than the first plausible alignment, so moving one sentence does not cascade into every following line being reported as changed. Common openings and endings are stripped before the search even starts, which is why a one-word edit in a long document resolves instantly.

Two levels, so one word reads as one word

Lines are compared first, then a removed line sitting against an added line is compared again inside itself. Change “Tuesday” to “Thursday” and you get one word highlighted, not a whole paragraph struck through. That second pass is gated on how alike the two lines are, so genuinely unrelated lines are not forced into a false pairing.

Options that change the comparison, never your characters

Ignoring case or whitespace works by comparing normalised copies while displaying the originals. Every character on screen and in the copied patch is exactly what you pasted: no line is silently trimmed, lowercased, or re-indented on the way through.

A unified patch with real hunk headers

The patch pane emits proper `@@ -a,b +c,d @@` headers with a configurable number of context lines, hunks merged when they sit close together, and a count of one written without its comma. These are the same conventions git and GNU diff use, so the output pastes straight into a review.

Numbers with the formula attached

Lines added, removed, changed, and untouched; words and characters gained and lost; and a similarity percentage that states how it was reached rather than asking you to trust it. The statistics are always measured at word level, so switching how a changed line is drawn never moves them.

It degrades where it would otherwise hang

Comparing two texts with nothing in common is quadratic work, so both the edit distance and the total search effort are capped. Past the cap a region is reported as one block replaced by another (still correct, no longer minimal), and the page says that happened rather than quietly serving a worse answer.

Diff questions

Moved blocks, invisible line endings, and what the @@ line is telling you.

What does a text diff checker actually do?+

It works out the cheapest way to turn one text into the other. The only moves available are deleting a line and inserting a line, so a “difference” is really an entry in an edit script: this line went, this line arrived, everything else stayed. That framing explains most of what a diff does that surprises people. It has no notion of a line being edited (an edit is a deletion and an insertion that happen to sit next to each other), and it has no notion of a paragraph being moved, only of one disappearing here and appearing there. This page adds a second pass on top: when a deletion and an insertion are close enough to be versions of the same line, it compares them again inside and shows you the words that actually moved.

Why does the algorithm minimise edits instead of finding “the” differences?+

Because there is no such thing as “the” differences: there are only stories about how one text became the other, and infinitely many of them are consistent with the evidence. You could always describe any change as “delete everything, insert everything”, which is correct and useless. The useful constraint is minimality: prefer the story with the fewest edits, because it keeps the most of the original in place and therefore reads closest to what a person actually did. Myers' 1986 algorithm finds such a story in time proportional to the size of the input multiplied by the length of that script, which is why two nearly identical files compare in milliseconds however long they are.

Is the shortest edit script unique?+

No, and that is worth knowing before you argue with a diff. Compare “a b c” with “a c b”: you can delete the b and insert it after the c, or delete the c and insert it before the b. Both are two edits; neither is more correct. Every diff tool breaks the tie by convention, not by insight. This one biases towards reporting deletions before insertions and towards taking matches as early as possible. So when a diff attributes a change to a line you did not touch, it is usually not wrong, it has simply chosen a different equally-short account of the same change. Git's `--patience` and `--histogram` algorithms exist precisely to make that tie-breaking feel more human on source code.

Why does a block I moved show up as a deletion and an insertion?+

Because “move” is not one of the operations. The edit script has exactly two verbs, delete and insert, so relocating a paragraph is spelled as its removal from the old position and its arrival at the new one. That is twice the red and green for a change that felt like one action. Some tools bolt on move detection afterwards by looking for a deleted block that matches an inserted block elsewhere, but it is a heuristic layered on top, not part of the algorithm, and it goes wrong when the moved block was also edited. The practical workaround is to make moves and edits separate revisions: move the section in one pass, change its wording in the next, and each diff stays readable.

Why do whitespace-only changes flood the diff, and when is ignoring them a mistake?+

Because a line is compared as a whole string. Re-indenting a file, converting tabs to spaces, or letting an editor strip trailing spaces on save changes every line it touches, so a formatting pass and a genuine edit are indistinguishable until you tell the comparison to look past spacing. Turning whitespace off is the right move for reviewing prose or reformatted code. It is the wrong move for anything where spacing is syntax: Python's indentation defines block structure, YAML's indentation defines nesting, and a Makefile recipe must begin with a literal tab rather than eight spaces. In those files a whitespace-only change is not cosmetic. It is the change, and hiding it will hide a real bug. This page keeps the two ideas apart: “ignore leading and trailing whitespace” forgives the edges while still reporting indentation, and “ignore all whitespace” forgives everything.

Why do two files that look identical show every line as different?+

Almost always line endings. Windows ends a line with a carriage return followed by a line feed, Unix and macOS use the line feed alone, and older Mac software used the carriage return alone. The characters are invisible, so a file that travelled through a Windows editor can differ from its original on every single line while looking exactly the same on screen. This page splits on all three terminators and compares the line content, so CRLF against LF does not produce a false wall of changes. It does still tell you the two sides use different endings, because that difference is real and will matter to git, to a shell script's shebang, and to anything reading the file byte by byte. The other invisible culprits are a non-breaking space pasted from a web page and a byte-order mark at the very start of a file.

What does the @@ line in the unified patch mean?+

It is a hunk header, and it tells a patch program where the following block belongs. `@@ -12,7 +12,9 @@` reads: starting at line 12 of the original file, seven lines are described here; starting at line 12 of the new file, nine lines are described here. The minus range always refers to the original and the plus range to the revision, and the counts include the unchanged context lines shown either side, not just the changes. A count of one is written without its comma, and an empty range is written against the line it follows, so a pure insertion after line 4 appears as `-4,0`. Below the header, a leading space means unchanged, a minus means removed, and a plus means added. Context is what lets a patch apply to a file that has drifted slightly: with three lines either side, a patch program can still find the right place after unrelated edits above it.

Why does word-level highlighting need a similarity threshold?+

Because pairing a deleted line with an inserted line is a guess, and a bad guess is worse than no guess. If two lines really are versions of each other, comparing them inside is exactly what you want. If they merely happen to be adjacent, the inner comparison finds the handful of short words and stray punctuation they share and produces confetti: a scattering of green and red fragments that is harder to read than “this line went, this line arrived”. The threshold is a ratio: the characters the two lines share, counted on both sides, divided by their combined length. One means identical, zero means nothing in common. Above the setting you choose, the pair is refined and shown word by word; below it, the two lines are reported as a straight replacement. Loosen it when comparing heavily rewritten prose, tighten it when a diff starts looking like tinsel.

How big can the two texts be, and what happens at the limit?+

Each side takes up to 200,000 characters or 10,000 lines, which is roughly a 40,000-word manuscript. There are two softer limits inside that. The line comparison stops searching once the edit script would run past 12,000 edits or the search exceeds its effort budget, because comparing two texts with nothing in common is quadratic work and would otherwise lock the tab; past that point the affected region is reported as one block replaced by another, and a note says so. Separately, a single line longer than 4,000 words or characters is refined by shared opening and ending rather than fully, which is again flagged rather than hidden. Every one of these limits produces a correct answer, just a coarser one than usual.

Can this tell me whether two pieces of code do the same thing?+

No, and no diff tool can. This compares text, not meaning. Renaming a variable consistently, reordering two independent function definitions, swapping single quotes for double quotes, or reformatting an argument list across three lines are all large diffs and zero behavioural change. Conversely, `>` becoming `>=` is one character and can be the whole bug. A diff is evidence about what was typed, not about what will happen, which is exactly why code review reads diffs and then runs the tests. If you want a comparison that understands structure rather than characters, you need a tool that parses the language, and the useful first step here is to normalise the formatting of both sides before comparing so that the diff is about content rather than layout.

More focused tools, ready when you are.

Explore the growing collection for calculations, documents, writing, and everyday work.

Browse all tools