All posts
Feature10 min read

Inside csvdiff.app — A Tour of the Diff, Viewer, and Cleanup Features

Column-level filters, match keys, side-by-side views, resolve-and-merge, AI summaries, single-file viewer, color rules, fill blanks, text format, column formats, drag-to-reorder columns, bulk replace, and export. A walkthrough of every feature in csvdiff.app.

Most CSV diff tools stop at "here are the rows that changed". That covers maybe a third of what you actually want when you open two files side by side. The other two-thirds — focusing on the columns that matter, matching rows by ID instead of position, picking which side wins for a merged export, getting a plain-English summary of what changed — usually require a script, a spreadsheet wizard, or a paid SaaS. csvdiff.app pulls all of it into one browser tab, and over the last few releases it has grown a second mode: drop a single file and you get a fast viewer with the cleanup tools an Excel user expects (color rules, fill blanks, trim & case, inline edit, column formats). This post walks through every feature in the order you tend to reach for them.

Row-level Diff with Status Pills

Drop two files in and the first thing you see is a unified diff table. Each row is tagged Modified, Added, Removed, or Unchanged, and changed cells highlight the old value next to the new value inline. No squinting between two windows.

Statusidnamerolestatus
Modified102Sara AhmedEngineerSenior Engineeractive
Added201David MillerDesigneractive
Removed088Layla HassanEngineerinactive
A unified row diff with inline old → new values.

Match Keys — Diff by ID, Not Row Position

Two exports of the same dataset will almost never come back in the same order. A positional diff treats every reordered row as a change, which is noise. Pick a match key column (id, email, sku, order_number) and csvdiff.app pairs rows across files by that key first, then computes cell-level diffs only on the genuine differences. Same export reordered? Zero changes. One row deleted, one added, three modified? You see exactly that, no false positives.

A good match key is unique and stable across both files. If your data has no single-column key, you can still diff positionally — but the match key is what makes the diff trustworthy on real-world exports.

AI Match Key Suggestion

When a file has thirty columns and three of them look key-ish, picking the right match key is half the battle. The AI Suggest button next to the match-key picker hands every column name and a sample of values to your configured LLM and gets back a ranked list — id at the top, then email, then sku — each with a confidence score and a one-line reason. Click pick on a row and the diff recomputes against that key. Your API key stays local; only column names and a few sample values are sent.

Column-Level Filters — Hide What You Don't Care About

A wide CSV is harder to read than a tall one. The Columns menu lets you toggle individual columns on and off, with a search box for files that have dozens of headers. There's also an "Only changed" switch that hides every column where the two files agree on every row — leaving just the columns where something actually moved. On a 40-column export with three differing columns, this turns 40 columns of scrolling into 3 columns of focus.

Columns3/9
  • idall equal
  • nameall equal
  • role
  • salary
  • departmentall equal
  • managerall equal
  • status
  • created_atall equal
  • updated_atall equal
Result · 3 of 9 cols shown
rolesalarystatus
The Columns menu with "Only changed" enabled — six unchanged columns collapse out, leaving the three that actually moved.

Sort, Pin, and Filter by Column

Every column header is a control surface. Click the header text to sort that column ascending, click again for descending, click a third time to clear. Click the pin icon to lock a column to the left edge of the scroll area — useful when you have an ID or name column you always want visible while you scroll horizontally through 30 other fields. And click the filter icon to open a value picker: a checklist of every distinct value in that column, with counts. Tick the values you want to keep and the table narrows to just rows where that column matches. Sort, pin, and value filters all stack — sort by salary descending, pin "name", filter "department" to just Engineering and Design, and you have a focused view in four clicks.

id
name
department2
salary
status
▲▼ Click header to sortPin to leftFilter by values
Sort caret, pin badge, and active value-filter on individual column headers.

Pinned columns stay anchored to the left while everything else scrolls. Combined with column visibility and value filters, you can shape a 50-column export into a 5-column working view without touching a spreadsheet.

Bulk Find-and-Replace from the Column Filter

Open any column's value filter and the same panel that lists distinct values doubles as a bulk-replace surface. Tick the values you want to rewrite, type the replacement, hit apply, and every matching cell in that column updates in place — across thousands of rows in a single click. The rewritten rows flash so you can visually verify the scope of the change, and the edits are non-destructive (export to commit them, or clear to revert).

Filter roleClear
Software Engineer
Apply
Preview · 27 cells
engineerSoftware Engineer18
senior engineerSoftware Engineer9
Search values…
engineer18
senior engineer9
designer6
manager4
analyst3
2 selectedlocal · no upload
After Apply · row flash3 updated
#role
1engineerSoftware Engineer
2senior engineerSoftware Engineer
3engineerSoftware Engineer
filter pinned to "Software Engineer" · click Clear to see all rows
Bulk-replacing two legacy role labels with their current names. Affected rows flash on apply.

Status Filters — Modified, Added, Removed

Above the table, six pills (Changes only, All rows, Unchanged, Modified, Added, Removed) act as a single-click filter on row status. "Changes only" is the default and usually what you want — it hides every Unchanged row so the table is just the deltas. Toggle Modified to audit edits, Added to review new records, Removed to confirm deletions.

Changes only12All rows84Unchanged72Modified6Added4Removed2

One click to slice the diff. Filters compose with column visibility and search.

Status filter pills with live counts. Click any pill to slice the table.

Search — Cross-Cell, Across Both Files

Press / and a search input takes focus. The query runs across every visible cell in both files at once, including row numbers — useful for tracking down a specific record by name, ID, or any value. The match count updates as you type, and the search composes with the column visibility and status filters so you can narrow first and search within the narrowed set.

employees.csv84 rows · 4 cols
sara
idnameroledepartment
102Sara AhmedSenior EngineerPlatform
145Sara KhanDesignerBrand
188Sarah LeeData AnalystInsights
3 matches in 84 rows/to focus search
Search filters across every visible cell in both files at once. Matches highlight inline.

View Modes — Diff, File A, File B

Sometimes a diff isn't what you need. The view switcher flips the same table between three modes: Diff (the unified comparison), File A (just file A as a viewer), and File B (just file B as a viewer). Same column visibility, same search, same sort — you don't lose your place when you switch contexts.

Single-File Viewer Mode

Diffing needs two files; viewing only needs one. Drop a single CSV (or JSON) and csvdiff.app skips the diff machinery entirely and opens the file in a clean viewer: paginated, virtually scrolled, with the same search, sort, pin, column visibility, and value filters you get in diff mode. The viewer is what you use when somebody hands you a 200k-row export and asks "what's in it?". Open in three seconds, scroll without lag, find what you need, close the tab.

orders_2026_q2.csv184,230 rows · 4 cols
search…
order_idcustomerskutotal
O-10242Ayesha KhanSKU-882$240.00
O-10243Sara AhmedSKU-104$98.50
O-10244John SmithSKU-882$240.00
O-10245Zain AliSKU-451$1,205.00
Showing 4 of 184,230/to focus search
Single-file viewer mode. Same toolbar as diff — search, sort, pin, value filters — minus the A/B comparison machinery.

Color Rules Per Column

Every column header in the viewer (and in the diff table when you switch to File A or File B mode) has a palette menu. Pick a rule and the cells in that column get a subtle tint that makes patterns obvious without changing the underlying data. Five rules ship today — heatmap (gradient by numeric value), category (a stable color per unique value), above/below average (green/red against the column mean), empty cells (amber on blanks), and duplicates (highlight values that appear more than once).

namesalarystatus
Ayesha$120,000active
Sara$98,000on leave
John$155,000active
Zain$87,000pending
Maya$142,000active
Heatmap · salaryCategory · status
Heatmap rule on the salary column. Indigo darkens with the value — extremes pop without sorting.

Fill Blanks From Above

Pivot-style exports leave grouping columns blank under their first row, because Excel renders them that way visually but the CSV inherits the blanks. The column menu has a one-click "fill blanks from above" toggle that copies the last non-empty value down into every blank below it, stopping at the next populated cell. The filled cells highlight green so the change is visible, and toggling the option off restores the original blanks without touching any manual edits you made in between.

Before
regioncityrevenue
WestSan Francisco$240k
emptySeattle$180k
emptyPortland$92k
EastNew York$310k
emptyBoston$145k
Fill blanks
After
regioncityrevenue
WestSan Francisco$240k
WestSeattle$180k
WestPortland$92k
EastNew York$310k
EastBoston$145k
Fill blanks toggled on for the region column. The filled cells highlight green and the change is fully reversible.

Text Format — Trim & Case

Stray whitespace and inconsistent casing are the two cheapest data-quality bugs to fix, and the two most tedious to fix by hand. The Text format menu on any column gives you a trim toggle (strip leading, trailing, and collapse internal whitespace) and a four-way case switch (None, lower, UPPER, Title). Changes are display-only until you export — the source CSV stays untouched in memory.

Format nameText
Case
NonelowerUPPERTitle
Preview
DAVID·JONESDavid Jones
··jane·SMITH·Jane Smith
Maria··GarciaMaria Garcia
Trim + title case on the name column. The strikethrough side is the raw value; the right side is what gets exported.

Drag-and-Drop Column Reorder

Every column header has a small drag handle on the left that appears when you hover. Grab it and the column lifts out of the row as a floating card that follows your cursor, while the original slot stays in place as a faded ghost. Move over any other column and that column lights up indigo — release to swap the two. It feels closer to Linear or Jira than to a spreadsheet, and it avoids the "scroll the page accidentally while reordering" trap of old drag implementations.

A few details that matter: the swap respects pinned-first ordering, so pinned columns only swap with other pinned columns and unpinned with unpinned — you never lose a pin by reordering. Reorder works in both modes, so the same gesture cleans up a diff view or a viewer view. And like every other state in csvdiff.app, the order lives in memory only; refreshing the tab starts you fresh, and your underlying CSV file never changes until you hit export.

id
name
region
status
amount
Source (ghost)Drop targetRelease to swap
Lift "name" out of the row, hover "status" — that column lights up indigo. Release to swap their positions.

Tip: combine drag-reorder with pin. Pin the two or three columns you actually care about, then drag-reorder them into your preferred sequence. Wide files become readable without filtering anything out.

Inline Edit and Header Rename

Click any cell to fix a typo in place. Click any header to rename the column. Both edits are non-destructive — they live in memory until you export, so a misclick is one Cmd-Z away from the original. For changes that span many rows, the bulk find-and-replace from the column filter (covered above) is the faster path; inline edit is for the one-off fixes that always come up when you scroll the file.

Column Formats — Currency, Dates, Numbers

A column of numbers can mean a dozen different things: dollars, percentages, durations, IDs, raw integers. The Format menu on every column lets you pick how the values render: currency (USD, EUR, GBP, and more), percent, number with separators, date and datetime (ISO, US, EU, relative), or scientific notation. The viewer detects a likely format from the column values and suggests one; you can override with one click, and AI Suggest will pick a format with reasoning if the data is ambiguous. Like the text format, this is display-only — your CSV bytes don't change until you export with "apply formats" turned on.

Format revenueReset
Detected USD currencyApply
Plain numberUSD currencyEUR currencyPercentScientific
Preview
240000$240,000.00
1205.5$1,205.50
92000$92,000.00
USD currency — values cluster in the $50k–$300k range with no decimals, consistent with USD revenue figures.
Ask AI to suggest format
Format menu on a numeric column. Detected as currency, with a one-click switch to scientific or plain number.

Smarter Numeric Sort

Sorting a column of "$1,200", "$98", "$10,000" alphabetically puts $10,000 between $1,200 and $98 — useless. The sort now detects numeric-looking values and sorts by their parsed magnitude, ignoring currency symbols, thousands separators, and stray whitespace. Same for percent columns and dates. The mixed case (a column of numbers with the occasional "N/A") still sorts numerically, with the non-numeric values grouped at the end.

Before · old string sort
revenueunsorted
  • $$1,205
  • $$240
  • $$10,200
  • $$98
  • $$3,450
After · numeric sort
revenueasc
  • $$10,200MIN
  • $$3,450
  • $$1,205
  • $$240
  • $$98MAX
A revenue column sorted by parsed numeric value rather than string order.

Resolve and Merge — Pick a Winner per Cell

Diffing is half the job; the other half is producing a single merged file. On every changed cell, click A or B to pick which side wins for the export. Row-level controls let you keep or drop entire Added/Removed rows. Bulk actions handle the common cases — "keep all from A", "keep all from B", "accept everything as new". The export honors every choice you made.

IDrolesalarystatus
102
AEngineerBSenior Engineer
A95,000B110,000
active
145Designer78,000
AactiveBarchived
Resolutions saved per cellExport merged
Per-cell A/B picker. The strikethrough side is dropped from the export.

Export — CSV or JSON

When you're happy with the resolutions, the footer has Download CSV and Download JSON buttons. The export uses your current filter and column visibility, so you can ship either the full merged dataset or just the changes-only slice. Everything is generated in the browser — the file goes straight from memory to your disk.

merged.csv resolved

84 rows · 9 columns · generated client-side

Download
The export reflects every per-cell pick and every column you kept visible.

AI Summary — Plain-English Diff

For files where you need to communicate what changed (a stakeholder, a PR description, a release note), the AI Summary popover ships the diff to your configured LLM and gets back a structured paragraph: counts by status, a few representative examples, and patterns it noticed (e.g. "all status changes were active → archived"). You bring your own API key — it never touches our server.

AI summaryGenerated locally
Modified
6
Added
4
Removed
2
  • Six employees received role and salary updates, all in the Platform department.
  • Four new hires were added across Engineering and Design.
  • Two records were removed — both had status set to "inactive" in file A.
A typical AI Summary output: counts, patterns, and standout examples.

Privacy — 100% Client-Side

Every feature above runs in your browser. The CSV parser, the diff algorithm, the merge logic, the export — none of it makes a network request with your data. The only optional exception is the AI summary, which uses a key you supply and goes directly to your chosen provider. For regulated data (PII, finance, health), this is usually the deciding factor.

Putting It All Together

A typical diff session: drop two CSVs, pick a match key (or accept the AI suggestion), switch to "Only changed columns", filter to Modified rows, search for the customer ID a teammate flagged, click B for the cells where the new values are correct, hit Download CSV. Three minutes, no scripts, no spreadsheet macros, no data leaving the tab.

A typical viewer session: drop one CSV, apply a heatmap to the salary column, run a duplicates check on email to catch double-imported rows, fill blanks down the region column so the file groups cleanly, trim and title-case the name column, format revenue as USD currency, and export the cleaned file. Same tab, same privacy guarantees, no spreadsheet — and no version of you wishing the CSV had come out cleaner from the source system.

That's the tool: built for the things you actually do with CSVs, not the things the demo shows.

Try it yourself

Ready to diff your files?

Upload two CSV files and see the differences in seconds. 100% client-side — your data never leaves the browser.

Start comparing →

Ready to diff?

Drop your files, see the deltas, export the merge. Takes 30 seconds.