Skip to content

Text Diff

Compare two versions of a document and see exactly what changed, computed in your browser with the jsdiff Myers algorithm. Diff by line, word, or character; read the result in a side-by-side split view or a unified “+”/“−” block; and optionally ignore whitespace or letter case. Additions and deletions are counted separately, and a rewritten line is shown as a single aligned pair rather than two scattered stripes.

How Text Diff works

  1. Paste the original text on the left and the new version on the right.

  2. Pick line or word granularity and hit Compare.

  3. Read the result in split or unified view.

  4. Use the additions and deletions summary to confirm the scope of a change.

When to use Text Diff

  • Comparing two drafts of a contract, brief, or article to confirm exactly which lines were rewritten before you sign off on the change.
  • Reviewing an edit someone sent back, with additions and deletions counted separately so you can gauge the scope at a glance.
  • Checking a copy-paste against its source to prove nothing was dropped, duplicated, or silently reordered.
  • Producing a review-ready patch by pasting the old and new version of a file and switching to unified view to copy the “+”/“−” block into a pull request.
  • Narrowing a change to a single altered word in a sentence by dropping from line granularity to word granularity.
  • Suppressing re-indentation and trailing-space noise on a line-level comparison by turning on ignore whitespace, so only real content changes remain.
  • Comparing two versions that differ only in letter case, and deciding whether that difference matters by toggling ignore case.
  • Reviewing a confidential document you cannot upload, since both panels are compared entirely on your own device.

Examples

Line diff of a one-word rewrite

Input

Left: “The launch is on Tuesday.
Invite the whole team.”  Right: “The launch is on Wednesday.
Invite the whole team.”

Output

Line 1 is shown as a modified pair — the Tuesday line on the left, the Wednesday line on the right, aligned as a single row. Line 2 is unchanged. The summary reports one addition and one deletion, because a modified row counts as both.

The rewritten line pairs a removal with an addition, so the split view zips them into one modified row rather than two disconnected stripes.

Word granularity isolates the change

Input

Left: “Ship the report by Friday.”  Right: “Ship the report by Monday.”

Output

Only “Friday” is tinted as removed and “Monday” as added; every other token is left unchanged.

Word mode diffs token by token, so a single substitution does not flag the whole line. Word and character modes always render in unified view.

Ignore whitespace hides a re-indent

Input

Left: “  const total = a + b;”  Right: “const total = a + b;” (leading spaces removed)

Output

With ignore whitespace on in line mode, the two are reported as identical — “The two texts are identical.” With it off, the line reads as a modified pair.

Ignore whitespace is a line-mode option only; it is disabled in word and character modes, where the spacing is often the thing you are inspecting.

How Text Diff works under the hood

The comparison is built on the jsdiff library, which implements the Myers diff algorithm — the same longest-common-subsequence approach used by Git. NeatKit calls one of three jsdiff functions depending on the granularity you pick: diffLines for line mode, diffWords for word mode, and diffChars for character mode. Each returns a flat list of segments tagged as added, removed, or unchanged, which is then turned into the rows you see.

In split view, that flat list is aligned into paired rows. A run of removed lines immediately followed by a run of added lines is zipped together offset by offset, so a rewritten line shows its old text on the left beside its new text on the right as a single modified row, rather than as a removal several rows above its replacement. Where a removed run and an added run are different lengths, the extra lines fall back to pure removals or additions with an empty counterpart.

The summary counts rows, not characters. An added row adds one to additions, a removed row adds one to deletions, and a modified row — a genuine rewrite — counts as one of each, because it both removed the old line and introduced the new one. The two texts are declared identical only when both additions and deletions come out at zero under the current options.

Ignore whitespace is passed straight through to jsdiff’s line comparison, so re-indentation and trailing-space changes stop registering as edits; it is deliberately unavailable in word and character modes. Ignore case applies in every mode. Character mode compares by code point through diffChars, which is why it is the most exact but also the slowest granularity on long inputs, and why a multi-code-point emoji can be split across a tint boundary.

One consequence of the Myers algorithm is worth knowing: appending a line to the end of a file can make the engine re-emit the previous last line as a removal plus an addition. NeatKit detects that pattern when it zips the rows — if the paired removed and added texts are byte-for-byte identical, the row is reclassified as unchanged, so you are not shown an edit you never made.

Everything runs in the browser. Files dropped onto either panel are read locally through the file reader, and neither the original nor the updated text is transmitted, which is what lets you compare an unreleased draft or a confidential contract without it leaving the page.

Common mistakes

  • Expecting ignore whitespace to work in word or character mode. It is a line-granularity option and is switched off in the other two, because there the whitespace itself is usually part of what you are trying to see.
  • Reading a modified row as two separate changes. When a line is rewritten, the split view pairs the old and new text as one row; the summary correctly reports it as one addition and one deletion, not two of each.
  • Running character granularity on a very large document and finding it sluggish. Character mode compares every code point, so it is the slowest case — switch to line mode for long files and reserve character mode for short strings where you need the exact edit.
  • Comparing text that contains emoji or combined accents in character mode and seeing a glyph tinted oddly. Character diffing works on code points, not grapheme clusters, so a multi-part emoji can straddle a boundary; line or word mode is the more readable choice for prose.
  • Forgetting to press Compare. The diff is computed as you edit, but the result only renders after you trigger the comparison, so an empty result panel usually just means the button has not been pressed yet.
  • Assuming split and unified show different data. They render the same underlying rows two ways — split places the versions side by side, unified stacks removals above additions with “−” and “+” markers for pasting into a review.

Frequently asked questions

All tools

Search NeatKit

Jump to a tool, a page, or change the theme.