Text Diff
Compare two texts line by line, word by word, or character by character, and get a unified diff you can apply with patch or git. Compared in your browser.
Where your data goes
| Using this page | Using the API, MCP or A2A | |
|---|---|---|
| Where it runs | In your browser. Both texts are compared in the page with jsdiff; nothing is uploaded, so confidential text never leaves your browser. | In a Cloudflare Pages Function at the Cloudflare data centre nearest the caller. |
| What leaves your device | Nothing you enter. After the page and its scripts load, no request
carries your input. The browser enforces this: the page's Content-Security-Policy
sets connect-src 'none' and form-action 'none', which
block fetch, XHR, WebSocket, EventSource, beacons and form posts.
| The server receives both texts in full, compares them in memory, and returns the differences. Your input is not stored or logged; only the per-call metadata row (operation, time, status, sizes) is recorded. For confidential text use the page, which compares in your browser and sends nothing. |
| Stored | Nothing leaves the page. No cookies, analytics or third-party scripts; the browser keeps only your View → Inline config choice. | Your inputs and results: never. What is stored is your client record (client ID, a SHA-256 hash of your secret, expiry, and the profile you registered with) and one metadata row per call: operation, time, transport, status, error code, duration, request and response sizes, and country. |
| Logged | Nothing (no requests are made). | Only the per-call metadata above, attributed to your client ID. Never parameters, bodies, results, or credentials. Cloudflare, as the host, also processes request metadata (IP address, full URL including the query string, headers) under its own policies, so put inputs in POST bodies. |
| Access | Open to anyone. | Requires a client ID and secret (how to get one). HTTPS only; TLS terminates at Cloudflare. |
Details and how to verify this yourself: Security & privacy.
User guide
The tool sits in a window that works like a desktop app: menus on the top row and the full-screen icon at its right (Esc leaves full screen). The set-up options described below are in Settings → Options…, an overlay, and the Settings menu also lists the common choices directly. To keep the options in view instead, choose View → Inline config; the page remembers that choice. Help → Keyboard shortcuts… lists the keys.
- Paste the original into Before and the changed version into After.
- Choose how to compare:
- Lines for code, configuration and logs;
- Words for prose;
- Characters for short strings, identifiers or a single changed line.
- Optionally tick Ignore whitespace or Ignore case.
- Read the result:
- the summary line counts what was added and removed;
- Changes shows both texts merged, with removed text struck through in red and added text underlined in green;
- Unified diff is the standard patch format. Copy it or download it as
changes.diff.
To apply the unified diff to a file, set both labels to the file’s path (e.g. src/app.ts) and run patch -p0 < changes.diff. With a/src/app.ts and b/src/app.ts labels, use git apply changes.diff or patch -p1.
Swap exchanges the two texts, which reverses the diff.
Specification
Algorithm. jsdiff’s implementation of Myers’ O(ND) difference algorithm, which finds a shortest edit script. When several shortest scripts exist, jsdiff’s choice is used.
Modes.
| Mode | Token | Counts in stats |
|---|---|---|
lines | a line including its line break; \n and \r\n both end a line | lines |
words | a run of ASCII letters, digits, _ and Latin-1/Latin Extended letters; every other non-space character (punctuation, CJK, emoji) is a token of its own | word tokens |
characters | a Unicode code point (an emoji is one character) | code points |
Options.
| Option | lines | words | characters |
|---|---|---|---|
ignore_whitespace | Lines compare equal if they match after trimming leading and trailing whitespace (so a\r\n equals a\n). Whitespace inside a line still counts | Whitespace between words is ignored (a b equals a b) | Not supported: 422 error. On the page the box is disabled |
ignore_case | Case-insensitive (toLowerCase) | Same | Same |
Without ignore_whitespace, whitespace is significant in every mode: in words mode, a b and a b differ.
Structured output.
changes: every piece of both texts, in order, typedadded,removedorunchanged, with its size (count) in the mode’s unit. A replacement is aremovedpiece followed by anaddedpiece.- Rebuilding the texts: concatenating
unchanged+removedvalues reproducesbefore;unchanged+addedreproducesafter. When an ignore option is set, unchanged pieces carry theaftertext. identical: true whenchangescontains nothing butunchanged, i.e. equal under the options.exact_match: compares the raw strings.
Statistics.
added,removed,unchanged: totals in the mode’s unit.change_blocks: number of contiguous runs of changed pieces.lines_added,lines_removed:+and-lines of the unified diff, asdiffstatcounts them.chars_added,chars_removed: code points in the added and removed pieces.
Unified diff.
- Granularity: always line-based, whatever the mode, using the same
ignore_whitespaceandignore_case. Context lines shown when ignoring come fromafter. - Headers:
--- <from_label>and+++ <to_label>, then hunks@@ -<start>,<count> +<start>,<count> @@withcontextunchanged lines around each change (default 3, as GNU diff). Changes separated by at most twicecontextunchanged lines (6 by default) share one hunk. - Counts in headers: jsdiff always writes the count, even when it is 1 (
@@ -11,1 +11,1 @@; GNU diff writes@@ -11 +11 @@).patchandgit applyaccept both. - Empty side: an empty range is written as start 0, count 0 (
@@ -0,0 +1,1 @@). - Missing final newline: a line without one is followed by
\ No newline at end of file. - Labels: a label containing non-ASCII characters, control characters,
"or\is quoted C-style, as Git does ("caf\303\251.txt"). - No differences:
unifiedis an empty string andhunksis empty.
hunks holds the same data as unified, with the header parsed into numbers and each line kept with its , - or + prefix (line breaks removed).
Limits.
- Text size: each text may be up to 200,000 characters (UTF-16 code units).
- Edit size: a comparison stops with a 422 error once the edit script would exceed 5,000 lines (
lines, and the unified diff in every mode) or 2,000 tokens (words,characters). Myers’ algorithm costs time proportional to text length × number of edits, so these caps bound the worst case. For heavily rewritten texts uselinesmode or compare smaller sections.
API & MCP
The same logic is available over HTTP and as MCP tools. Unlike this page, these run on the server: see where your data goes.