Skip to content

Text Diff & Compare

Compare two texts instantly in your browser. Side-by-side view with inline word-level highlights, unified-diff export, ignore case / whitespace / blank lines. 100% private — your text never leaves your device.

No Tracking Runs in Browser Free
All comparison runs locally in your browser. Your text never leaves this device.
Ignore options
Reviewed for parity with `diff -u` output, intra-line LCS correctness, and accessibility (ARIA roles, screen-reader change announcements, RTL/LTR handling). — Go Tools Text Tooling Team · May 21, 2026

What is Text Diff?

Text diff is a structured comparison of two text documents that finds the smallest set of insertions and deletions transforming one into the other. The output makes the change visible: green for added lines, red for removed, side-by-side or in unified-patch form (the `---/+++/@@` format used by `git`, GitHub, and the Unix `patch` command).

Under the hood every modern diff is a Longest Common Subsequence (LCS) algorithm. Eugene Myers' 1986 O((N+M)D) paper is the canonical efficient implementation; classical dynamic programming (used here, with common prefix/suffix trimming) is simpler and works perfectly for typical web inputs. After lines line up, neighbouring remove + add pairs are run through a second token-level LCS so the renderer can highlight only the words that actually changed inside a line — what reviewers call intra-line or word-level diff.

Why not just compare strings character-by-character? Because edits are rarely flat: inserting one line in the middle of a 200-line file shifts every line below it. A naïve `===` would call all 199 lines different. LCS tells you the truth: one line added, 199 unchanged.

This tool runs the entire comparison in your browser. No upload, no temporary file, no log. Safe for proprietary code, redlined contracts, private logs, anything you'd be uncomfortable pasting into a third-party server. Need to diff JSON instead? Use the structural JSON Diff so key order and whitespace stop being noise. Comparing two configs in YAML or CSV? Convert with YAML to JSON or JSON to CSV first, then diff with the right tool for the format.

// Two strings that look 'mostly the same' but a naïve check disagrees
const a = 'hello world';
const b = 'hello, world!';

// Character equality
a === b; // false — but only 3 characters actually changed.

// LCS-style diff (this tool, at line + word granularity)
// → 1 line modified, inline highlight: 'hello[, ]world[!]'
// → unified patch:
//   --- original
//   +++ modified
//   @@ -1 +1 @@
//   -hello world
//   +hello, world!

Key Features

Side-by-Side + Unified

Switch between the visual two-column view (for human review) and the canonical unified-diff patch format (for `git apply`, code-review tools, bug reports).

Inline word-level highlighting

When two lines are paired as modified, only the changed tokens carry a colored background. Your eye finds the edit instantly instead of scanning 80 characters.

Ignore case / whitespace / blanks

Four independent toggles: case, all whitespace, trailing whitespace only, blank lines. Replicates `git diff -i -w -b` in a couple of clicks.

Unified diff export

Copy a clean `---/+++/@@` patch with three lines of context. Drops straight into a PR comment, a bug report, or `patch -p1`.

100% browser-based

Inputs never leave your device. No upload, no analytics on text. Works offline once the page is loaded. Safe for proprietary code and confidential prose.

Unicode + RTL aware

Splits tokens on Unicode word boundaries. Arabic, Hebrew, CJK content compares cleanly; line-ending variants (CRLF, LF, CR) are all normalized.

Examples

Code review — one variable rename

function getUser(id) {
  const u = db.users.find(x => x.id === id);
  return u;
}
function getUser(userId) {
  const u = db.users.find(x => x.id === userId);
  return u;
}

Side-by-side view highlights every line containing the rename, while inline word diff dims the unchanged tokens so reviewers see exactly which identifier changed.

Contract edit — one clause added

1. The service is provided as-is.
2. Either party may terminate with 30 days notice.
3. Disputes are resolved in California courts.
1. The service is provided as-is.
2. Either party may terminate with 30 days notice.
2a. Termination notice must be in writing.
3. Disputes are resolved in California courts.

A single inserted clause (line 2a) is the only difference. Surrounding context lines stay clean — useful for redlining contracts or policy docs.

Log investigation — request timing changed

GET /api/users 200 14ms
POST /api/orders 201 88ms
GET /api/orders/42 200 21ms
GET /api/users 200 14ms
POST /api/orders 201 4200ms
GET /api/orders/42 500 21ms

Two lines change. Inline highlight shows 88ms → 4200ms latency drift and 200 → 500 status code. Status quo for an incident timeline.

Trailing whitespace — toggle 'Ignore trailing'

  margin: 0;  
  padding: 0;
  border: none;
  margin: 0;
  padding: 0;
  border: none;

Without the option, line 1 reports a difference (trailing spaces). Toggle 'Ignore trailing spaces / tabs' and the diff goes to zero — the same trick `git diff -b` does.

How to Use

  1. 1

    Paste both versions

    Original text on the left, modified text on the right. Live diff renders as you type; large inputs (>200 KB combined) switch to a manual Diff button.

  2. 2

    Turn on the ignore options you need

    Ignore case, ignore all whitespace, ignore trailing spaces, or ignore blank lines — each independent, persisted between visits.

  3. 3

    Read the diff or grab the patch

    Side-by-Side for human review, Unified for the `---/+++/@@` patch format. Copy unified diff sends a clean patch to your clipboard for code review or `patch -p1`.

Common Diff Pitfalls

Whole file 'changed' after a Windows-vs-Unix copy

If you paste from Notepad on Windows into a Unix-edited original, every line will show \r differences. Turn on 'Ignore trailing spaces / tabs' to silence the CR characters.

✗ Wrong
Diff: 200 modifications (all because of trailing \r)
✓ Correct
Ignore trailing spaces / tabs → 2 real changes

Indentation-only diff is screaming

Reformatting tabs ↔ spaces explodes line-by-line diffs. 'Ignore all whitespace' collapses the diff to the real semantic changes.

✗ Wrong
Diff: 87 modifications (all are indent changes)
✓ Correct
Ignore all whitespace → 4 actual changes

Identical paragraphs flagged because of one blank line

Adding or removing a single empty line in prose can mis-align an entire region. 'Ignore blank lines' fixes it without touching content.

✗ Wrong
Diff: paragraph 2 'completely changed' (one blank line moved)
✓ Correct
Ignore blank lines → no changes in paragraph 2

Diff says 'identical' but the files are different

Almost always a case or whitespace ignore option left on from a previous session. Open the Ignore options panel — every toggle is shown there. Turn them all off if you want byte-strict comparison.

✗ Wrong
0 differences shown, but `cmp` says the files differ
✓ Correct
Disable all Ignore options → real diff appears

Pasted JSON looks like 'everything changed'

Text diff treats key order as significant; JSON does not. For JSON payloads use the dedicated JSON Diff tool — it ignores key order and respects type strictness.

✗ Wrong
Text diff on JSON: 100% of lines changed (just a key reorder)
✓ Correct
<a href="/tools/json-diff">JSON Diff</a>: 0 differences

Diff truncated warning ignored

Above 5,000 lines per side the input is clipped. If the warning shows, switch to command-line `diff -u file1 file2` or `git diff --no-index` — both stream and handle gigabytes.

✗ Wrong
Pasted a 20,000-line log — only first 5,000 lines diffed
✓ Correct
`diff -u a.log b.log` in terminal handles full file

Common Use Cases

Code review snippet
Drop two versions of a function into the boxes to see a rename, a removed branch, or a new guard clause at a glance. Inline word highlighting is faster than scanning the GitHub diff for a one-line change.
Contract / policy redline
Paste yesterday's contract vs today's revision. Inserted clauses jump out; unchanged paragraphs collapse to gray. Export the unified patch for the legal review trail.
Log timeline investigation
Compare an SRE's pre-incident log slice against the during-incident slice. Latency, status code, and frequency drift surface immediately without `awk`.
Prose / draft revision
Paste a draft and your editor's version. Inline word diff shows exactly which sentences were rewritten — invaluable for accepting or rejecting changes one at a time.
Translation review
Diff an old translation against a re-translation to confirm the new copy preserves meaning, structure, and placeholders. Toggle 'Ignore trailing spaces' to silence noise that translators commonly introduce.
Config / .env file audit
Compare two `.env`, `docker-compose.yaml`, or shell rc files. With 'Ignore blank lines' on, the diff focuses on functional differences instead of formatting churn.

Technical Details

LCS with prefix/suffix trimming
Common leading and trailing lines are stripped before running the dynamic-programming LCS. A 'two 2,000-line configs with one changed line' diff collapses to a 1×1 DP table and renders in under a millisecond.
Token-level intra-line diff
Adjacent remove + add hunks are paired and tokenized via Unicode word/non-word/whitespace runs. A second LCS pass produces the green/red token spans that make modified lines readable.
Unified diff = git/patch compatible
Output follows the `---/+++/@@ -L,C +L,C @@` format defined for GNU patch and used by Git, GitHub, and every code-review tool. Apply with `pbpaste | patch -p0`.
Input cap at 5,000 lines per side
Beyond the cap the diff truncates and warns. For multi-megabyte inputs use command-line `diff -u` or `git diff --no-index` — they stream and handle gigabytes.

Best Practices

Pick the ignore options before reading
Trailing-space, CRLF, and case noise drown out signal. Toggle the right options first; the diff is much easier to read and you stop training yourself to skim past 'fake' changes.
Use Unified when sharing, Side-by-Side when reviewing
Visual columns are for your eyes. Unified patches are for everyone else's terminals. A copied unified diff drops into a Slack message, a Jira comment, or `patch -p1` without translation.
Sanity-check with similarity %
If two files are 'almost the same' but the similarity score is 30%, you have a line-ending or whitespace problem. Toggle 'Ignore all whitespace' and re-check before reading the diff.

Frequently Asked Questions

Is the text I paste sent to your server?
No. Every comparison runs in JavaScript inside your browser. Your text is not uploaded, logged, stored on disk, or sent to any third party. Only your UI preferences (view mode and ignore-option toggles) are saved to localStorage so the page remembers them next visit — never the text. You can verify this by opening DevTools → Network: zero requests fire when you click Diff.
What's the difference between text diff and JSON diff?
Text diff compares line by line — perfect for prose, code, logs, contracts, config files. JSON Diff understands JSON's data model: key order is irrelevant, types are strict, arrays can be matched by key. If you paste JSON into a text diff, key reorders and whitespace differences will be flagged as changes; JSON Diff ignores them. Use text diff for unstructured content, JSON Diff for API responses and config payloads.
How do I ignore whitespace, case, or blank lines?
Click the 'Ignore options' panel above the diff. 'Ignore case' makes A and a equal. 'Ignore all whitespace' collapses every space, tab, and newline before comparison. 'Ignore trailing spaces / tabs' only strips end-of-line whitespace — the standard `git diff -b` behavior. 'Ignore blank lines' drops empty/whitespace-only lines before diffing. Each option is independent and persists across visits.
What's a unified diff (and when do I copy it)?
A unified diff is the `---/+++/@@` text format used by `patch`, `git apply`, GitHub PRs, and most code-review tools. Click Copy unified diff to grab a patch with three lines of context around every change — paste it into a bug report, a code-review comment, or a `patch -p1` command and it applies cleanly. Side-by-side is for humans, unified diff is for machines (and code reviewers who think like machines).
Why does the diff show whole lines changed when I only edited one word?
It doesn't — look closer. The full line is highlighted because something on it changed, but inside the highlight only the changed tokens carry the bright background (green for added, red strikethrough for removed). This is intra-line word diff: the line context stays readable while your eye lands on the exact edit. If two consecutive lines were both modified, both show inline highlighting.
How are CRLF vs LF line endings handled?
Both are recognized. The diff splits on \r\n, \n, and bare \r, so Windows CRLF, Unix LF, and old-Mac CR text all line up correctly. If you want to flag line-ending changes specifically, leave 'Ignore trailing spaces / tabs' off — \r will surface as a trailing character. To erase line-ending noise entirely, turn 'Ignore all whitespace' on.
How large can the two inputs be?
The diff runs on the main thread, so practical limits are about 5,000 lines or 1 MB per side; above that we clip and show a warning. Live diff disables above 200 KB combined and switches to a manual Diff button. For multi-megabyte files, use command-line `diff -u` or `git diff --no-index` — they stream and handle gigabytes.
What about diffing code? Does it know my language?
The diff is language-agnostic: it sees lines and tokens, not syntax. That's a feature for review snippets, config edits, and copy-pasted patches. If you want semantic code diff (renamed function across files, AST-level), use git, GitHub PR view, or a dedicated structural diff tool. For 90% of code-review situations — eyeballing a function, comparing two snippets — line + word diff is what you want.
Why does a single edit sometimes appear as a removed line plus an added line?
When too much of a line changed for word-level highlighting to be useful, the diff reports it as separate remove + add lines so the structure stays clean. The same heuristic gives readable output for prose rewrites and for code blocks that were rewritten rather than edited. Switch to Unified view to see the classic `-`/`+` pair format used in patches.
How is the % match similarity calculated?
It's the number of unchanged lines (after applying ignore options) divided by the larger of the two line counts, clamped to 100%. Two identical inputs are 100%. Adding one new line to a 100-line file gives 99%. Replacing every line is 0%. Useful for quickly judging 'is this a small edit or a wholesale rewrite' before reading the diff.
Can I share a diff with a colleague?
Yes, two ways. (1) Click Copy unified diff and paste the patch into chat, Slack, or a PR comment — anyone with a terminal can `patch < clip` it. (2) Take a screenshot of the side-by-side panel for visual review. We deliberately do not provide a 'share by URL' button: that would require uploading your text, which we don't do.
Does the diff handle right-to-left languages like Arabic or Hebrew?
Yes for the text content — lines and tokens are Unicode-aware. The interface uses logical CSS directions, so on RTL locales the gutter and line columns flip naturally. Inside a diff cell the text direction follows the content, so Arabic and Hebrew strings render correctly while the +/- markers stay aligned to the gutter.

Related Tools

View all tools →