What is a text diff and how does it work?
A text diff is the computed difference between two pieces of text, showing what was added, removed, or changed. It's the algorithm behind Git's git diff, every code review tool, every IDE merge conflict resolver, every "track changes" feature in Word and Google Docs, and most database synchronization tools. The most influential algorithm — "An O(ND) Difference Algorithm and its Variations" by Eugene Myers (1986) — still powers Git, GNU diff, and most production diff tools 40 years later.
Conceptually, a diff finds the longest common subsequence (LCS) between two texts and reports everything that's NOT in that LCS as either an addition (in the new file) or deletion (only in the old file). The result is the smallest possible "patch" that turns the old text into the new.
Different tools display diffs differently:
- Unified diff — Git's default. Shows old/new on alternating lines, prefixed with
-and+. - Side-by-side diff — old on left, new on right, aligned. Easier to read for prose; what most code review tools (GitHub, GitLab, Phabricator) use as default.
- Inline diff — single column with strikethrough for deletions and color for additions. Compact but harder for big changes.
Diff granularity — line vs word vs character
| Granularity | Best for | Tool |
|---|---|---|
| Line-level | Code, configs — most common diff type | git diff, GNU diff, this tool |
| Word-level | Prose, documentation, blog posts | git diff --word-diff, Google Docs |
| Character-level | Tiny strings, IDs, version numbers | JS libraries (diff-match-patch), Word |
| Hunk / block | Showing context around changes | git diff -U3 (3-line context) |
| Semantic / AST | Understanding logic changes in code | difftastic, semantic-diff (research-grade) |
This tool uses line-level diff with optional word-level highlighting within changed lines. That matches what you'd expect from git diff or a typical code-review interface.
Compare code online, find difference in code, string compare — same workflow, different phrasing
Search variants for the same intent: "compare code online", "find difference in code", "string compare online", "online string compare", "js compare online", "online diff checker", "diff compare online". They all describe pasting two pieces of text into a tool and seeing what changed. The diff checker above handles all of them — code in any language, plain strings, JSON blobs, log lines, configuration files. Each H3 below addresses one specific phrasing.
Compare code online — what makes a good code diff
A good code diff is more than a line-by-line minus/plus. It also needs (1) whitespace-aware mode (toggle off "ignore whitespace" when indentation matters; toggle on for refactor reviews), (2) word-level highlighting within changed lines so a one-character rename doesn't paint the whole line red, (3) handling of long lines without forced wrap that distorts the diff. The tool above does all three. For comparing two files in different formats — e.g., one minified and one beautified version of the same JavaScript — run both sides through the JS minifier's beautify mode first, then diff.
Find difference in code — without copy-pasting into git
Three scenarios where this is faster than git diff: (1) one of the two versions isn't in version control (a teammate's Slack paste, a production config you SSH'd into, an AI-generated patch); (2) the files are in different repos that don't share history; (3) you want to share the diff visually with someone who doesn't run a CLI. Paste both versions into the tool above, take a screenshot of the highlighted output, and share. For longer-term tracking, commit both versions to a scratch branch and use git diff branch1..branch2.
String compare online — for non-code text comparison
"String compare" usually means smaller payloads than full files: SQL query strings between two app versions, error messages between two log lines, two API responses to the same call. The diff above is identical for short strings — paste left and right, see character-level differences. For very short strings (under 100 chars) where you only care about exact equality, JavaScript's === in the browser console is faster; the diff tool's value is when you want to see what differs, not just whether they differ.
JS compare online — for JavaScript snippets and JSON payloads
"JS compare online" usually means one of two things: (1) compare two JavaScript source snippets (different versions of the same function, two implementations being benchmarked), or (2) compare two JSON payloads (API responses, config objects). The diff above handles both. For JSON specifically, beautify both sides through the JSON formatter first so structural differences don't get drowned out by formatting noise. For sorted-key comparison (where key order doesn't matter), pass each side through jq -S '.' at the CLI before pasting.
Online diff compare — when to use a browser tool vs CLI
Browser-based diff is fastest for one-off comparisons: paste two snippets, scan the highlighted output, copy the merged result. CLI diff wins when you're already in a terminal, scripting batch comparisons, or working with files too large to paste. The tool above handles the browser case; for the CLI, diff -u old.txt new.txt produces a unified diff that GitHub, Phabricator, and every code-review platform understand. Quick comparison alongside related tasks: format the inputs first with the JSON formatter or SQL formatter so whitespace differences don't drown out the real changes.
Git diff vs online diff compare — a practical workflow
Use git diff branch1..branch2 -- path/to/file when both versions are committed. Use this online diff when one or both versions live outside Git: a teammate's Slack paste, a production config you SSH'd into, an AI-generated patch you haven't applied yet. The display semantics match — additions in green, deletions in red, unchanged lines neutral — so muscle memory from git diff transfers directly. For comparing minified JS or compressed JSON, run each side through the JS minifier's beautify mode first.
Common diff use cases
- Code review — comparing two versions of a file before merging a PR. The most common use, and what most diff tools optimize for.
- Configuration drift detection — comparing the running config of a server against the canonical version in your repo. Catches manual changes that didn't make it into version control.
- API response comparison — running the same API call before and after a deploy and diffing the responses. Catches subtle regressions in serialization or default values.
- Log file analysis — diffing yesterday's log output against today's. New error messages stand out instantly.
- Document version comparison — comparing two drafts of a contract, blog post, or specification. Lawyers and editors use this all day.
- Database schema migration verification — comparing
SHOW CREATE TABLEoutput before and after a migration to verify changes. - Detecting copy-paste content theft — paste suspect content alongside the original; diff highlights how much was copied verbatim.
Diffing in 8 environments
Git (the most common diff in 2026)
# Diff working tree vs last commit
git diff
# Diff between two commits
git diff abc123 def456
# Side-by-side via tool integration
git difftool -t vimdiff # or vscode, meld, kdiff3, beyond compare
# Word-level diff for prose
git diff --word-diff
# Show only filenames changed
git diff --name-only
# Statistics summary
git diff --stat
# Diff a specific file across all commits
git log -p -- path/to/file.txt
GNU diff (POSIX command line)
# Unified format (most readable)
diff -u old.txt new.txt
# Side-by-side
diff -y old.txt new.txt
# Recursive directory diff
diff -ur old_dir/ new_dir/
# Ignore whitespace changes
diff -u -w old.txt new.txt
# Generate a patch and apply it
diff -u old.txt new.txt > changes.patch
patch old.txt < changes.patch
JavaScript (diff library)
import { diffLines, diffWords, diffChars } from 'diff';
const changes = diffLines(oldText, newText);
changes.forEach(part => {
const sign = part.added ? '+' : part.removed ? '-' : ' ';
console.log(sign + part.value);
});
// Word-level
const wordChanges = diffWords(oldText, newText);
// Generate unified-format patch
import { createPatch } from 'diff';
const patch = createPatch('file.txt', oldText, newText, 'old version', 'new version');
Python (difflib — built-in)
import difflib
old = open('old.txt').readlines()
new = open('new.txt').readlines()
# Unified diff
for line in difflib.unified_diff(old, new, fromfile='old', tofile='new'):
print(line, end='')
# HTML side-by-side
html = difflib.HtmlDiff().make_file(old, new)
# Quick similarity ratio (0–1)
ratio = difflib.SequenceMatcher(None, old_str, new_str).ratio()
Go (golang-diff)
import "github.com/sergi/go-diff/diffmatchpatch"
dmp := diffmatchpatch.New()
diffs := dmp.DiffMain(oldText, newText, false)
fmt.Println(dmp.DiffPrettyText(diffs))
Online tools beyond Git
- Beyond Compare — paid, best-in-class folder diff (Windows/Mac).
- Meld — open-source 3-way diff, great for merge conflicts.
- VS Code's built-in diff — open two files, right-click → "Compare Selected".
- JetBrains IDEs — built-in diff, supports code-aware highlighting.
- difftastic — modern AST-aware diff. Treats
{x: 1, y: 2}and{ "y": 2, "x": 1 }as the same.
Common diff problems & fixes
- "Every line shows as changed." Caused by line-ending mismatches (CRLF vs LF). Normalize with
dos2unixfirst or usegit diff -w. - Trailing whitespace makes diff noisy. Use
diff -worgit diff --ignore-all-spaceto focus on meaningful changes. - Reordered keys in JSON show as huge changes. Sort keys before diffing, or use
jq --sort-keyson both sides first. - Auto-formatter ran across the file. Looks like a massive refactor. Rebase onto a "format-only" commit, mark it in
.git-blame-ignore-revs, then diff the actual logic changes. - Binary files diff as gibberish. Most diff tools don't handle binary. Use
git diff --binaryfor transport or specialized tools (xxdiff for hex). - Patches don't apply cleanly. The base file changed since the patch was created. Use
git apply --3wayor merge tools.
Diff best practices for 2026
- Keep PRs small. A 50-line diff is reviewed in 10 minutes; a 500-line diff in days. Break big changes into stacked PRs.
- Format before commit. Save formatting changes for separate commits so logic diffs aren't drowned in whitespace noise.
- Use
.gitattributesfor binary & minified files. Mark them asbinaryso Git doesn't try to diff them. - Diff JSON with
jq --sort-keysfirst to get clean output regardless of key order. - Use
--word-difffor prose. Far more useful than line-diff for documentation, blog posts, and contracts. - Set up
git config diff.algorithm histogramfor better diff results on refactored code. - For visual diff in PRs, configure your platform's "render" mode. Markdown, JSON, and image diffs render specially in GitHub/GitLab.
- Don't reformat & logic-change in one commit. Reviewers can't tell formatting from substance. Two commits = two PRs of clean review.