CSV Diff

Compare two CSV files row-by-row and highlight added, removed, changed rows

Free CSV diff tool that compares two CSV files in your browser — by row index or by a key column — and shows a color-coded table of added, removed and changed rows with the exact cells that differ. Nothing is uploaded. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is the difference between index and key-column matching?

Index matching compares row 1 with row 1, row 2 with row 2, and so on — best for ordered exports. Key-column matching pairs rows that share the same value in a chosen column, such as an id, so reordered or inserted rows are matched correctly rather than appearing as a cascade of changes.

Compare two CSV exports and see exactly which rows were added, removed or changed — matched by row position or by a key column you choose, with the differing cells highlighted. Everything runs in your browser; no file is uploaded.

How it works

Both inputs are parsed with an RFC 4180 reader that handles quoted fields, embedded commas and escaped quotes ("" inside a quoted field becomes a single "). The first row becomes the header.

Then the tool compares rows in one of two modes:

  • By row index — row n of the left file is compared against row n of the right file. This is correct for ordered exports where rows do not move.
  • By key column — you pick a column such as id or email; rows are paired by their value in that column. A row whose key exists only on the right is added; only on the left is removed; on both with any differing cell is changed. Reordered or inserted rows are matched correctly.

For each changed row, the tool compares cells by column name (the headers are unioned across both files), so a column present in only one file is shown as added/removed cells.

+ row added     (green)
- row removed    (red)
~ row changed   (amber)  — only the differing cells are highlighted

Why key-column matching is almost always better

To understand why index matching fails, consider a product catalogue. You have 1 000 rows in both exports, but someone inserted a new product at row 50 in the updated file. Every row from 50 onward now compares against the wrong partner: the index-matched diff reports 951 “changed” rows — nearly the entire file — when in reality only one row was added and perhaps a handful of prices changed. Using the sku column as the key means the tool pairs rows by product identity, and the diff shows exactly what changed: one addition and the actual price modifications.

A key column diff is also stable against reordering. If a data team re-sorted the export by a different column between two snapshots, index matching would again report nearly every row as changed, while key matching ignores the reorder entirely.

Working with different column sets

When the two CSVs have different headers the tool unions them. For example, if the left file has id,name,email and the right adds phone:

  • Rows matched by key show a “phone” cell as added on the right side.
  • The change highlight appears only on the phone column for those rows.
  • Columns removed on the right side appear as removed cells in the diff.

This makes CSV diff useful for schema migrations: paste the before and after exports to see not just data changes but which columns were added or dropped.

Worked example

Given a left file:

id,name,price
1,Widget A,9.99
2,Widget B,14.99
3,Widget C,4.99

And a right file with a price change and a new row:

id,name,price
1,Widget A,9.99
2,Widget B,12.99
3,Widget C,4.99
4,Widget D,7.99

Using id as the key column produces:

  • Row 2 (Widget B): price cell changed from 14.99 to 12.99 — highlighted amber.
  • Row 4 (Widget D): added — highlighted green.
  • No false positives even though the file length changed.

Tips

  • Always prefer a key column when comparing database or spreadsheet exports — index matching turns a single inserted row into a wall of false “changes”.
  • If a key value appears more than once, the tool matches the first unmatched occurrence on each side, then treats remaining duplicates as added/removed.
  • Trailing blank lines are ignored; surrounding whitespace inside unquoted cells is preserved as-is so you can spot accidental spacing differences.