Skip to content
FormatKit

Free online source code diff

Code diff that ignores the reformat

This code diff is free and runs without an account: paste two revisions, pick the language, and it compares them with whitespace-only, indentation-only, comment-only and trailing-comma changes filtered out before anything is drawn. Blocks of three lines or more that moved elsewhere in the file are labelled as moves rather than counted as a deletion plus an unrelated insertion, and the comparison is anchored on lines unique to both files — patience diff — so a hunk starts where you made the edit instead of at the nearest matching brace. Both boxes accept 5 MB of source.

  • 100% free
  • No signup
  • 15 languages highlighted
  • Moved blocks detected
  • Skip comment-only edits
Changes to treat as noiseSkip

Paste both revisions. Pick the language to get highlighting and to teach the comment filter what a comment looks like.

How to compare two versions of a source file

Three steps to a diff that only shows what you changed.

  1. Paste both revisions and name the language

    The version in the repository goes on the left, your working copy on the right; a ⌘V or Ctrl+V that lands outside the two boxes fills whichever one is still blank. Choosing the language does two jobs: it turns on highlighting, and it tells the comment filter what a comment looks like, since // means nothing in Python and # means nothing in Go.

  2. Turn off the noise you did not write

    Four filters work independently — whitespace-only, indentation-only, comment-only and trailing-comma changes. Whitespace-only is on by default because a formatter run is the single most common reason a diff is unreadable. Comment-only stripping runs over the whole file first, so a /* … */ block that opens on one line and closes six lines later is handled as one comment rather than four broken ones.

  3. Read the summary before the columns

    It gives you +added −removed across N blocks, a violet badge counting the blocks that moved rather than changed, and how many of the rewritten lines differ only in indentation. Moved blocks are tinted violet in both panes and labelled “moved to line …” and “moved from line …”, so a function lifted to the top of the file is one fact instead of a deletion and an unrelated insertion.

Technical specifications

AlgorithmPatience diff — lines unique to both sides become anchors, Myers O(ND) runs on the gaps between them; anchoring recurses 24 levels before it hands over
Languages15 with keyword, string, number and comment highlighting, plus plain text; four comment grammars (// with /* */, #, --, <!-- -->)
Noise filtersWhitespace-only, indentation-only, comment-only and trailing-comma changes, each switchable on its own and applied before the comparison, not after
Comment handlingA scanner that respects single quotes, double quotes, template literals and escapes, and carries block-comment state across lines — a URL inside a string keeps its slashes
Moved blocksRuns of 3 lines or more, matched against up to 48 candidate destinations per starting line, labelled in both panes with the line they came from or went to
Speed5,000 lines with half of them rewritten: 1.8 ms, against 81 ms for the minimal Myers script on the same input. Highlighting adds 12 ms and comment stripping 10 ms per 5,000 lines
Size and rendering5 MB a side; 3,500 rows drawn, with untouched stretches collapsed to a count and 5 lines of context kept around every change and every move
Price and processingFree with nothing to register for and no ceiling on how many revisions you put through it; tokenising, filtering and the comparison itself all run in this browser tab

Frequently asked questions

How do I diff two source files without the formatter noise?

Tick the filters for the changes you did not make by hand: whitespace-only, indentation-only, comment-only and trailing-comma. Each one normalises both sides before the comparison rather than hiding rows afterwards, so a file that Prettier or Black reindented from two spaces to four, added trailing commas to and re-wrapped comments in comes out showing only the logic you actually edited.

What is patience diff and why does it read better on code?

Patience diff matches the lines that occur exactly once in both files first, and only then compares what lies between those anchors. Bram Cohen described it in 2006 after noticing that minimal diffs align the wrong braces: a closing } is identical to every other closing }, so the shortest edit script happily pairs your new one with someone else's and reports a change that starts halfway up the previous function. A unique line — a function signature, an import, a distinctive string — cannot be mismatched that way, so anchoring on those produces hunks that start where a human would say the change starts. It is rarely the smallest possible diff, and that is the trade: git ships the same idea as --patience and its refinement --histogram for exactly this reason. This page anchors first and falls back to Myers between anchors, or wherever no unique line exists.

Can it tell a moved function from a delete plus an add?

Yes — that is what the violet blocks are. After the line comparison, every deleted line and every inserted line is re-matched against the other side, and any run of three lines or more that turns up intact somewhere else is relabelled as a move with the destination line number attached. A line diff has no concept of a move on its own, which is why lifting a 40-line function to the top of a file normally reads as 40 deletions and 40 unrelated insertions. Git added --color-moved in 2.15 for the same reason. Moves are matched on the same normalised text as the diff, so a block that was moved and reindented still registers as a move when the whitespace filter is on.

Does “skip comment-only changes” break on URLs inside strings?

No, because the comment filter is a small scanner rather than a regular expression. A regex that deletes everything after // also deletes half of const endpoint = "https://api.example.com/v2", which would quietly change what is being compared — the worst possible failure for a diff. The scanner tracks single quotes, double quotes, template literals and backslash escapes, and only treats a comment opener as one when it is outside all of them. It also carries block-comment state from line to line, so a /* that opens on line 12 and closes on line 18 removes those seven lines and nothing else.

Will a tabs-to-spaces conversion show every line as changed?

Not with the whitespace filter on, which is its default state. Both sides get every run of spaces and tabs collapsed to one space and both ends trimmed before they are compared, so a file converted from tabs to four spaces compares as unchanged. If you want the opposite — to see indentation changes but not count them as rewrites — untick whitespace and tick indentation-only instead: that trims the leading and trailing whitespace only, and the summary then tells you how many of the changed lines differ in nothing else.

Which languages get syntax highlighting?

Fifteen, plus a plain-text mode that highlights nothing: JavaScript and TypeScript, JSX and TSX, JSON, Python, Go, Rust, Java and C#, C and C++, PHP, Ruby, shell, YAML, SQL, CSS and SCSS, and HTML and XML. Highlighting is per line and keyword-based rather than a full parse, which is why it costs about 12 milliseconds for 5,000 lines and never gets in the way of the comparison. The language choice matters more for the comment filter than for the colours — it selects between four comment grammars: // with /* */, #, --, and <!-- -->.

Is the source I paste here uploaded anywhere?

No, and for this page that is the point: proprietary source is exactly what people are nervous about pasting into a web tool. Both revisions are compared, highlighted and rendered by JavaScript inside this tab, no request is made while you work, and nothing survives closing it.

About diffing source code specifically

The shortest edit script between two files is not always the clearest one, and code is where the gap is widest. Source is full of lines that are identical to each other — }, });, a blank line, an import — and a minimal algorithm has no reason to prefer one of them over another. Add a function and the shortest script will often claim you edited the tail of the function above it and added the head of yours, because pairing the braces that way saves an edit. Patience diff sidesteps the whole class of mistake by refusing to guess: it matches only the lines that appear exactly once on each side, treats those as fixed points, and compares the gaps between them independently. Nothing forces those anchors to be the cheapest choice, and that is the point.

Moves are the other thing a line diff cannot see. Every line-based algorithm produces deletions and insertions and nothing else, so reordering two functions or extracting a block into a helper is reported as if you had deleted forty lines and written forty unrelated ones. The information is recoverable after the fact — the deleted lines and the inserted lines are right there and can be matched against each other — which is what this page does with runs of three lines or more, and what git diff --color-moved has done since Git 2.15. Three lines is a deliberate floor: shorter runs of boilerplate match each other constantly and labelling them as moves is noise dressed up as insight.

Filtering reformat noise is the part people usually try to do with a regular expression and regret. Comments cannot be stripped by pattern, because the pattern that removes // to end of line also removes the second half of every URL in a string literal, and the change is silent — you get a clean-looking diff of text neither file contains. It needs a scanner that knows what a string is, which is a hundred lines of work and the difference between a filter you can trust and one you cannot. The same caution applies in reverse when the file is structured data: a JSON config compared as text will report reordered keys and reindented blocks as changes forever, so compare it by key path instead, and reach for the plain diff checker when what you actually need is the minimal script and a patch to send on.

Your source stays in the tab

Nothing you paste here is transmitted. Parsing, highlighting, comment stripping and the comparison itself all run as JavaScript in this tab, so an internal repository’s code can be compared without it reaching a server, a log or a third party.