Compare Two Code Snippets

Paste the old and new version to get aligned columns with only the changed words marked — or a clean unified patch, a merged word-diff stream, or change stats.

Try:
Diff

About this tool

Paste an old and a new version of a function, a config file, a query, or any other block of text and get the difference back in the shape you need: two aligned columns, a clean unified patch, one merged word-diff stream, a count summary, or a structured JSON report.

Two things make the result readable on real code. First, the line alignment is a patience diff — lines that appear exactly once on both sides act as anchors, so a duplicated } or a moved blank line doesn't drag the rest of the comparison out of step. Second, a changed line pair is refined inside the line: only the tokens that actually changed are marked, using the familiar [-removed-] / {+added+} convention.

Everything runs locally in WebAssembly — the snippets never leave the browser.

Worked example

Comparing

fn main() {
    println!("hi");
}

with

fn main() {
    println!("hello");
    println!("world");
}

produces, in the default side-by-side view:

 1   fn main() {                     |  1   fn main() {
 2 ~     println!("[-hi-]");         |  2 ~     println!("{+hello+}");
                                     |  3 +     println!("world");
 3   }                               |  4   }

1 line added, 0 lines removed, 1 line changed, 2 lines unchanged

The ~ marks a changed pair, + a pure insertion, - a pure deletion, and the unchanged prefix println!(" is left alone because only the string literal moved. Switch View to stats on the same input and you get:

Lines:      3 left / 4 right
Added:      1
Removed:    0
Changed:    1
Unchanged:  2
Similarity: 50.0%
Word-level:  1 removed / 1 added inside changed lines

Inputs

Limits and edge cases

FAQ

What do the [-…-] and {+…+} markers mean?

They are the git diff --word-diff convention. [-hi-] is text present only on the left (removed), {+hello+} is text present only on the right (added). Everything outside the markers is identical on both sides. In the side-by-side view each column shows only its own marker type; in the word-diff view both appear inline in one merged stream. Set Highlight inside changed lines to Off if you'd rather see whole lines marked without any inline markers.

When should I use character level instead of word level?

Word level splits a line into identifiers, punctuation, and whitespace runs, so colorcolour is reported as one whole identifier swapped. Character level narrows that to the single inserted u (colo{+u+}r). Character level is the better choice for typo hunting, renamed symbols that share a stem, and numeric literals; word level reads better on ordinary code edits, where a per-character diff of a rewritten expression turns into confetti.

If I turn on ignore case or ignore whitespace, does my code get rewritten?

No. Both options affect matching only. const B = 2; and const b = 2; compare equal with ignore-case on, so the line is no longer reported as changed — but any line that is shown keeps its exact original casing, spacing, and indentation. Ignore-whitespace collapses runs of spaces and tabs and trims line ends for the comparison, which is the quick way to tell a reformat apart from a real edit.

Why did some unchanged lines disappear from the output?

That's the Context lines setting. Only that many unchanged lines are kept around each change; longer unchanged runs collapse into a … N unchanged lines … marker so a small edit in a big file doesn't bury you. Raise it to see more surrounding code, or set it to 0 to see only the changes themselves. It applies to the side-by-side, unified, and word-diff views; stats and json always cover the whole input.

Can I apply the result as a patch, or feed it to another tool?

Yes. The unified view emits a standard --- / +++ / @@ patch with no inline markers and no trailing summary, so it stays valid input for git apply or any patch-applying tool. For programmatic use pick json, which returns the counts, the similarity, and every row with its line numbers plus the equal/delete/insert spans inside changed lines.

How large an input can it handle?

Up to 1 MB per side. That is roughly 25,000 lines of ordinary source, and the error message names both the limit and the size you sent if you go over. Very long individual lines are handled by a separate guard: past 400 tokens on either side of a changed pair, intra-line refinement is skipped and the line is marked whole. Splitting a minified file onto multiple lines first gives a far more useful comparison.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool diff-code 'fn main() {
    println!("hi");
}' 'right=fn main() {
    println!("hello");
    println!("world");
}'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/diff-code/?left=fn%20main%28%29%20%7B%0A%20%20%20%20println%21%28%22hi%22%29%3B%0A%7D&right=fn%20main%28%29%20%7B%0A%20%20%20%20println%21%28%22hello%22%29%3B%0A%20%20%20%20println%21%28%22world%22%29%3B%0A%7D&view=side-by-side&granularity=word&ignore_case=true&ignore_whitespace=true&context=3&line_numbers=true&width=60

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.