How the comparison is built
The diff is computed with the Myers algorithm, the same family of algorithm that git uses: it finds the shortest edit script that turns the left text into the right one, so unchanged material is matched even when large blocks have moved apart. Nothing is compared position by position, which is why inserting a line at the top does not mark the entire file as changed.
In line mode a removed line and an added line that sit next to each other are tested for similarity before being paired: they are treated as one edited line when they share at least 30% of their characters, or when both are 8 characters or shorter. A paired row then gets a word-level diff painted inside it, so you see the three words that changed instead of two entirely red and green lines.
When the two lines are not similar enough they stay a delete plus an add. That threshold matters: painting a word diff across two unrelated lines produces a stripe of noise that is harder to read than simply showing that one line went and another arrived.
Lines, words or characters — which to use
Lines is the right default for anything with structure: source code, configuration, CSV, logs, JSON, a Markdown draft. It gives line numbers on both sides, collapses long unchanged stretches and produces a patch you can copy.
Words suits prose, where an edit is rarely a whole line: a rewritten paragraph shows as the handful of words that actually changed. Word splitting uses Intl.Segmenter, so Korean, Japanese and Chinese are segmented properly instead of being treated as one enormous word for lack of spaces.
Characters is for short strings where a single symbol matters — an API key, a hash, a regular expression, a phone number, an ID that fails validation for a reason nobody can see. On a long text it produces more noise than signal, which is why it is not the default.
What each ignore option actually does
- Ignore line endings (on by default) strips a trailing carriage return before comparing, so a Windows CRLF file and a Unix LF file with identical content come out identical. This single option is the answer to most “everything is marked as changed” reports.
- Ignore whitespace makes the line comparison treat runs of spaces and tabs as equivalent, so a re-indented block stops being a change. It applies to the line comparison, which is where reformatting noise lives.
- Ignore case compares in lower case at every granularity, including inside the word-level painting of an edited line.
- Ignore blank lines removes empty and whitespace-only lines from the comparison but keeps the original line numbers on both sides, so a number in the result still points at the right line in your editor.
One more thing happens without an option: a newline is added to the end of both texts before the line comparison. Without it, jsdiff reports the last line of a file that ends without a newline as different from the same last line in a file that ends with one — the classic “\ No newline at end of file” false positive.
Comparing JSON structurally
Two JSON documents that describe the same thing can look completely different as text: keys in another order, two-space indentation against four, one on a single line. A text diff calls all of that a change, and none of it is.
Turn on JSON mode and both sides are parsed, then compared as data and re-rendered in a canonical form. Key order and formatting stop mattering and what remains is the values that actually differ. It is opt-in and never automatic: it needs both sides to parse, and it changes what the line numbers refer to, so the choice stays yours.
Use it for API responses, configuration files and fixtures. For a JSON file you also want to keep, run it through the JSON formatter first: two documents formatted the same way often need no structural diff at all.
Reading and exporting the result
The summary counts added, removed and modified rows, and counts separately how many of the modified rows differ only in whitespace — a quick way to tell a real change from a reformat before you read a single line.
Long runs of unchanged lines are folded with three lines of context on each side; click the “⋯ unchanged lines” bar to unfold one, or set the context to show everything. Press n and p to jump from one change to the next, which is faster than scrolling a thousand-line file.
Copy patch produces a git-style unified body: a space in front of unchanged lines, a minus in front of removed ones and a plus in front of added ones, with an edited line emitting both. It is the diff body only — there are no @@ hunk headers or file names — so it reads well in a code review comment, a commit message or a chat thread, but it is not a file you can feed to git apply.
Size limits and what happens at them
- Above 200 KB of combined text a word or character diff falls back to a line diff, and the result says so. A character diff of two 100 KB documents is a job measured in minutes, not milliseconds.
- Above 5 MB combined the comparison is refused outright rather than freezing the tab.
- Up to 5,000 rows are rendered. The algorithm also runs under guards — an edit-distance ceiling and a two-second timeout — and when a guard trips the tool degrades to a line diff and tells you, instead of returning a partial result that looks complete.
If a big comparison degrades and you need the detail, narrow the input: compare the section you care about rather than two whole files. A word diff of one chapter is more useful than a line diff of a book.
Where your text goes
Nowhere. The comparison runs in this tab with the diff library bundled into the page, and the two texts are kept in this browser’s localStorage so a reload does not lose them. There is no account and no server call, which is worth knowing before you paste a contract draft or a production config into a comparison tool.
Share diff packs both texts into the URL fragment after `#d=` — JSON, deflate-compressed, base64url-encoded, up to 8 KB compressed. Browsers never send a fragment in an HTTP request, so a shared comparison cannot appear in any web server’s access log. It is still a link, though: anyone who has it can read both texts.
Files dropped on either side are read with the browser’s file API and never uploaded: .txt, .json, .csv, .md, .log and other plain-text types. The file name is shown above the panel so a side-by-side comparison of two versions stays labelled.