Skip to main content

Diff Checker

Compare two texts line by line and see exactly what changed. Optional whitespace and case insensitivity, with a word-level view inside changed lines.

Your data never leaves the browserUpdated: July 2026
Difference
0added0removed0unchanged

Enter text on both sides and the line by line difference appears here.

Key Takeaways

  • Windows ends lines with CRLF while Linux and macOS use LF, so an untouched file can diff as completely rewritten.
  • This tool folds CRLF and lone CR to LF before splitting, so a line-ending change alone never produces a diff here.
  • LCS alignment has no concept of a move: a relocated block appears once as a deletion and once as an insertion.
  • The same Turkish or accented letter can exist as one code point or as a letter plus a combining mark, and those two forms compare as different.

Nothing changed, yet the whole file is red

You open a pull request for a one-line fix and the review screen shows 340 deletions and 340 insertions. You read the file top to bottom and nothing is actually different. Everyone who has seen this screen reaches the same conclusion at the same speed: the change is real, it is just made of characters that do not render.

Two causes account for almost every instance. Either the line-ending convention changed, or an editor stripped trailing whitespace on save. Neither leaves a visible mark, and both touch every line in the file.

Line endings, the CRLF and LF problem

Windows terminates a line with two characters, carriage return and line feed, written \r\n. Linux and macOS use a single \n. A colleague who opens a file on Windows and saves it without typing anything adds one invisible \r to every line, and as far as version control is concerned every line is now different.

bash
# The review shows no visible difference, but Git counts the file as modified$ git diff --stat src/utils/format.ts | 340 ++++++++++++++++----------------- # Make the hidden characters visible:$ cat -A src/utils/format.ts | head -2export function slugify(input: string) {^M$  return input.trim();^M$#                    ^^^ CRLF ending             ^^^ a plain LF would show only $ # The durable fix lives in the repository, not in one developer's config:$ echo "* text=auto eol=lf" > .gitattributes$ git add --renormalize .

git config core.autocrlf is a per-machine patch. It works for you and does nothing for the next person who clones the repository, which is why the same argument resurfaces every few months. A committed .gitattributes applies to everyone and settles it once.

You will not see line-ending noise in this tool. Before either side is split into lines, \r\n and standalone \r are folded to \n, and a trailing newline is not allowed to invent a phantom empty final line. Paste one side from a Windows machine and the other from a Unix one and the comparison still reflects the content.

Why a moved block shows up twice

The comparison runs on a longest common subsequence. The engine takes the lines from both sides and finds the longest sequence that appears in both while preserving order. Anything in that sequence is unchanged; everything else is a deletion or an insertion. Order is the only rule it enforces.

Move a function from the bottom of a file to the top and its lines can no longer be part of a common subsequence, because taking them would break the ordering. The result is a deletion where the block used to be and an insertion where it now lives. That is not a shortcoming to be fixed, it is what a line-oriented diff means, and it is why "this block only moved" is a comment a human has to write.

Note

For very large inputs, if the LCS table would exceed 4 million cells the engine falls back to a positional comparison and tells you so. In that mode a single inserted line shifts everything after it, so read the alignment as approximate rather than exact.

Trailing whitespace and character-level detail

Trailing whitespace is the second great source of review noise. Many teams enable "trim trailing whitespace on save" precisely because of it, and the pain arrives when only half the team has it enabled: the moment one of them opens an old file, lines nobody touched show as modified. Agreeing on the setting matters more than which way you agree.

To silence whitespace differences for one comparison, use the ignore-whitespace option. It collapses runs of whitespace and trims the ends, but only for matching purposes. Every row you see on screen carries the original text, never the normalized form, because showing someone a document they did not write is worse than showing them noise.

Knowing which line changed is often not enough. When one word changes inside a long sentence, the line diff gives you a red row and a green row and leaves you to spot the difference by eye. The inline view splits that line into words and the whitespace between them and runs the same alignment again, so the single changed word is highlighted directly. Tokenization keeps combining marks attached to their base letter, which is what stops accented text from being sliced into individual characters.

Two identical-looking strings that are not equal

Unicode allows one letter to be written two ways. The letter "ğ" can be a single code point, or it can be "g" followed by a combining breve. On screen the two are indistinguishable; in the file they are different bytes. The single-code-point form is called composed (NFC) and the multi-code-point form decomposed (NFD).

SourceTypical formEffect on a diff
Windows and Linux editorsComposed (NFC)Behaves as expected
macOS filenamesDecomposed (NFD)Two identical-looking names compare as different
Text copied out of a PDFMixedSome letters fail to match
A record read from a databaseDepends on the columnVaries by source
One word, several byte sequences. Indistinguishable by eye, distinct to a comparison.

This engine deliberately never calls normalize(). Normalizing would hide the difference, and hiding it means you never learn that your data has a real problem. If two lines look identical here and still compare as different, the same mismatch is very likely breaking your search, your sorting and your deduplication somewhere else. The fix belongs at the source, by normalizing on write, not in the tool that reported it.

Frequently Asked Questions

Why is every line showing as changed?
Almost certainly a line-ending change. A file saved with CRLF on Windows differs on every line from the LF version on Linux. Commit a .gitattributes containing * text=auto eol=lf and run git add --renormalize . to settle it for the whole repository.
Can I ignore whitespace differences?
Yes. The ignore-whitespace option collapses runs of whitespace to a single space and trims both ends before comparing. It affects matching only; the text displayed in each row is always the original.
Is the text I paste uploaded anywhere?
No. The comparison runs entirely in your browser and no request is made. Once the page has loaded you can go offline and the tool keeps working.
Can I compare files instead of pasted text?
The tool works on two text areas, so you paste the contents in. For two files already in a repository, git diff or diff -u is the more direct route; this is aimed at quickly comparing two things you have on the clipboard.
Why did a line I moved appear twice?
A line diff is order-sensitive. A moved block cannot belong to the common subsequence, so it is reported as a deletion at the old position and an insertion at the new one. There is no separate "moved" classification; recognizing it is the reviewer's job.