Diff Checker

Compare two blocks of text and see exactly what changed, line by line, word by word or character by character. Use it when two config files look identical but behave differently, and you need to find the one line out of 40 that differs.

Original
Changed
Differences

1 Reading the output

Green with a plus

Present in the changed version and not in the original. In line mode the marker covers a whole line. In Words and Characters mode the added text is highlighted in green inside the running text, without a plus sign.

Red with a minus

Present in the original and gone from the changed version.

Gray with a space

Identical on both sides. These unchanged lines give you the context around each change.

A move shows as both

Cut a block from the top and paste it at the bottom, and you get a removal and an addition. A line-based diff treats position as part of the content, so a moved block counts as two edits.

2 Picking a mode

Use Lines for code and config, Words for prose. Lines is the default, and it fits anything where a line is a meaningful unit. Words is better for prose, because a single edited word in a long paragraph would otherwise mark the whole paragraph as changed. Characters is the last resort for invisible differences: a Unicode dash where a hyphen should be, a non-breaking space pasted in from a document, or a trailing carriage return from a Windows editor.

Ignore whitespace helps when one side was reindented and you only want to know whether the content changed. It strips leading and trailing whitespace from each line before comparing, so a block pushed two spaces to the right no longer shows as changed. It also ignores the carriage return at the end of Windows lines, which makes it the quickest fix when one file uses CRLF line endings. Spaces in the middle of a line still count.

3 How it works underneath

The tool computes the longest common subsequence (the longest run of lines both sides share, in order) of the two inputs, the same idea behind diff and git diff. Whatever is not in that shared subsequence is either an addition or a removal. The comparison runs in your browser, so a production config or a customer export never leaves your machine. The work grows with the product of both sizes, so the tool stops at 2,000 lines per side in Lines mode and 6,000 tokens per side in Words or Characters mode (in Words mode, each run of spaces counts as a token too). For larger files, run git diff --no-index locally.

How to use the Diff Checker tool

  1. Paste the original version into the left panel and the changed version into the right.
  2. Pick a mode in Compare by: Lines for code and config, Words for prose, Characters when you are hunting an invisible difference.
  3. Tick Ignore whitespace if one side was reindented and you only care whether the content changed.
  4. Read the Differences panel below. In Lines mode, green with a plus is an addition, red with a minus is a removal and gray is unchanged context. The count of added and removed lines sits in the panel header.
  5. Click Swap Sides if you pasted the inputs the wrong way around. Copy Diff puts a plain-text, line-by-line version with + and - prefixes on the clipboard.

How to diff two files or strings in the shell, JavaScript and Python

Command line

# Unified diff, the format everything else understands
diff -u old.conf new.conf

# Ignore whitespace-only changes
diff -u -w old.conf new.conf

# Side by side, which is easier to read for short files
diff -y --width=160 old.conf new.conf

# Compare two files with git's algorithm, even outside a repo
git diff --no-index old.conf new.conf

# Only tell me whether they differ at all
cmp -s old.conf new.conf && echo same || echo different

JavaScript / Node.js

// npm i diff
const Diff = require("diff");

const a = "listen 80;\nserver_name example.com;\n";
const b = "listen 443 ssl;\nserver_name example.com;\n";

for (const part of Diff.diffLines(a, b)) {
    const sign = part.added ? "+" : part.removed ? "-" : " ";
    process.stdout.write(part.value.replace(/^/gm, sign));
}

// Word-level, better for prose
Diff.diffWords("the quick fox", "the slow fox").forEach((p) => {
    if (p.added || p.removed) console.log(p.added ? "+" : "-", p.value);
});

Python

import difflib

a = open("old.conf").readlines()
b = open("new.conf").readlines()

# Unified diff, same format as the diff command
for line in difflib.unified_diff(a, b, "old.conf", "new.conf", lineterm=""):
    print(line)

# How similar are two strings, 0.0 to 1.0
print(difflib.SequenceMatcher(None, "colour", "color").ratio())

# Did they mean one of these?
print(difflib.get_close_matches("recieve", ["receive", "retrieve", "relieve"]))

Common errors and how to fix them

Every single line shows as changed
The line endings differ. One file uses CRLF and the other LF, so no line matches. Tick Ignore whitespace here, or normalize the files first with dos2unix, sed -i 's/\r$//', or git config core.autocrlf.
A block that only moved shows as removed and added
Line-based diffs treat position as part of the content, so a move is two edits. git diff --color-moved highlights the pair as a move, but the underlying algorithm still records a removal and an addition.
The diff is enormous after reformatting
Turn on Ignore whitespace, or run both sides through a formatter first so indentation and line wrapping match before comparing.
Two JSON files with the same data produce a huge diff
Key order and indentation differ. Format both with the same settings first, or use the JSON diff tool, which compares parsed objects instead of text.
The comparison is slow or refuses to run
The algorithm's cost is quadratic in the number of tokens, so the tool stops at 2,000 lines or 6,000 words or characters per side. Switch to Lines mode, which has far fewer tokens, or run git diff locally for large files.

Good to know

The unified format used by patches, pull requests and git diff carries the same information plus a header per hunk. For example, @@ -12,7 +12,9 @@ means the hunk starts at line 12 and covers 7 lines in the old file and 9 in the new one. patch and git apply read that header along with the context lines to place the change, which is why a patch still applies after unrelated edits elsewhere in the file.

Specifications and references

This tool follows the specifications below. Read them when you need the exact normative wording, for example to settle an edge case between two implementations.

Frequently Asked Questions

How does the comparison work?

It finds the longest common subsequence of the two inputs (the longest run of lines both share, in order), the same idea git diff uses. Whatever is left over is marked as added or removed. A line that only moved still shows as a removal and an addition, because its position is part of the content.

Can I compare word by word instead of line by line?

Yes. Set Compare by to Words when two lines differ by a single word and the line view is too coarse to show it. Use Characters for the smallest differences, such as a stray non-breaking space or a curly quote.

Does it ignore whitespace?

Only when you tick Ignore whitespace. It strips leading and trailing whitespace from each line before comparing, so a reindented file or one with Windows line endings stops showing every line as changed. Spaces inside a line still count.

Is there a size limit?

Yes. The comparison runs in your browser and its cost grows with the product of both sizes, so the tool stops at 2,000 lines per side in Lines mode and 6,000 tokens per side in Words or Characters mode. For larger files, git diff --no-index on the command line has no such limit.

Can I compare JSON?

Yes, but format both sides with the JSON formatter first so each key sits on its own line. For a comparison that ignores key order, use the JSON diff tool, which compares the parsed structure instead of the text.

Related

Comparing JSON or CSS? Run both sides through the JSON formatter or the CSS formatter first so the structure lines up and the diff stays small. To confirm two files are byte-for-byte identical, compare their hashes in the MD5 generator.

More Text & Content Tools

Browse all text & content tools

Copied to clipboard!