The last CSV that cost me an afternoon was a 40 MB export from a client's WooCommerce store. I double-clicked it, Excel decided the SKU column was a date, and 2024-11-3 was suddenly what used to be 2024-11-3 โ except it wasn't, it was a product code. Excel had helpfully rewritten it. By the time we noticed, the "cleaned" file had already been re-imported and a few hundred products had SKUs that pointed at nothing.
That is the problem with opening a CSV in a spreadsheet application. A spreadsheet is not a viewer, it's an editor with opinions. It coerces types, it strips leading zeros from ZIP codes and phone numbers, it reinterprets anything that looks vaguely like a date, and it does all of this before you have looked at a single row. Sometimes you just want to see the file โ check the column names, confirm the row count, find the record that broke the import, and get out.
I build toolz.dev and I read other people's CSV exports constantly โ Stripe payouts, database dumps, analytics extracts, plugin migration files. So I built the CSV Viewer to be the boring, honest option: it parses the file, shows you exactly what is in it, and changes nothing. No type coercion, no autocorrect, no upload. Paste the text or drop the file, and it renders as a table you can search and sort.
TL;DR: A CSV viewer parses delimited text and renders it as a table without editing or coercing values. The CSV Viewer auto-detects whether your file uses commas, semicolons, tabs, or pipes, handles RFC 4180 quoted fields (commas and newlines inside cells, doubled quotes), warns you about ragged rows and duplicate headers, and exports to normalised CSV or JSON. Everything runs in your browser โ the file is never uploaded, and values stay strings so leading zeros survive.
What is a CSV file, really?
CSV stands for comma-separated values, and that name is responsible for a decade of bugs, because two of the three words are unreliable.
The values are not always separated by commas. Locales that use a comma as the decimal separator โ most of continental Europe โ export with semicolons instead, because 1,50;2,75 is unambiguous and 1,50,2,75 is not. Excel in a German or French locale does this by default. Analytics and database exports often use tabs, and log pipelines frequently use pipes. Any of these is still colloquially a "CSV".
And the values are not always plain. The moment a value contains the delimiter, the format needs an escape hatch, and RFC 4180 provides one: wrap the field in double quotes. Inside those quotes, the delimiter is just a character. A quote character itself is escaped by doubling it. And a quoted field may contain literal line breaks, which means a single logical record can span multiple physical lines in the file.
That last point is where naive parsers die. If your code is line.split(',') โ and I have written that line, and so have you โ then this file will destroy it:
id,name,note
1,"Smith, John","He said ""hi""
on the second line"
2,Ada,plain
Three columns, two records. A split-on-comma parser sees four fields in row two, panics on the stray quotes, and treats the wrapped line as a third record. A proper parser walks the string character by character, tracking whether it is currently inside quotes, and produces exactly what the file means. The CSV Viewer does the second thing.
Key features of the CSV Viewer
Automatic delimiter detection
Paste a file and the tool guesses the delimiter before it does anything else. The naive approach is to count characters and pick the most frequent one, which fails immediately on prose โ a notes column full of English sentences contains far more commas than a semicolon-delimited file has semicolons.
So the detection scores consistency instead of frequency. It takes the first ten non-empty lines, counts each candidate delimiter (comma, semicolon, tab, pipe) outside of quoted sections, and rewards the candidate that produces the same count on every line. A real delimiter appears exactly columns - 1 times per row, every row. A comma inside prose appears irregularly. Consistency wins, frequency only breaks ties. If it still guesses wrong โ and it will, on files with one column โ you can override it from the dropdown.
RFC 4180 quoted field parsing
The parser is a character-level state machine, not a regex and not a split. It tracks one boolean: are we inside a quoted field? Inside quotes, delimiters and newlines are ordinary characters, and a doubled "" emits a single literal quote. Outside quotes, a delimiter ends the field and a newline ends the record. CRLF, LF, and bare CR line endings are all accepted, because Windows exports, Unix exports, and old Mac exports all exist and all end up in the same inbox.
This is the difference between a viewer that shows you Smith, John in one cell and one that shows you "Smith and John" in two.
Search across every column
The search box filters rows with a case-insensitive substring match against every cell in the row. It is not fuzzy, it is not a query language, and that is deliberate โ when you are hunting for the record that broke an import, you have an order ID or an email address and you want the row that contains it, immediately.
Search runs on the parsed data in memory, so it is instant on files of any size your browser can hold, and it composes with sorting: filter first, sort the result, export what is left.
Numeric-aware column sorting
Click a column heading to sort by it. This sounds trivial and is not, because CSV has no types โ every value arrives as a string, and string sorting puts 100 before 9 and 2024-3-1 before 2024-11-1.
The sort inspects the values: if every non-empty cell in the comparison parses as a number (with thousands separators stripped), it compares numerically. Otherwise it falls back to a locale-aware string comparison with numeric collation, so item2 sorts before item10. Empty cells always sink to the bottom, in both directions, because a blank is not a small value โ it is a missing one, and burying missing data at the top of a descending sort is how you fail to notice it.
Data quality warnings
Two structural problems get flagged before you go any further.
Ragged rows. If a row has more or fewer fields than the header, something is wrong upstream: an unquoted delimiter inside a value, a truncated export, a stray newline. The viewer pads short rows and truncates long ones so the table still renders, then tells you exactly how many rows were affected. That count is the number I check first, because a file with three ragged rows out of ten thousand has a data bug that a COPY into Postgres will surface at 3 a.m.
Duplicate column names. Two columns called id will silently overwrite each other in almost every downstream consumer โ pandas will rename them, a JSON conversion will keep only the last, and a SQL import will error. The viewer names them in the warning banner so you can fix the header before it matters.
CSV and JSON export
The export panel re-serialises whatever is currently on screen โ filtered, sorted, whatever you did. The CSV export applies correct RFC 4180 quoting on the way out, which makes it a decent way to normalise a file that arrived with inconsistent quoting. The JSON export converts the table to an array of objects keyed by the header row, which is what you want when you are feeding a script or an API.
One deliberate choice: exported values stay strings. "01234" does not become 1234. A CSV column full of digits might be a quantity, or it might be a ZIP code, an account number, a phone number, or a SKU โ and there is no way to tell from the data. Coercing to numbers throws away leading zeros permanently, which is the exact bug that started this article. If you want numbers, cast them explicitly on the other side, where you know what the column means.
It runs entirely in your browser
The file is read with the FileReader API and parsed in JavaScript. Nothing is uploaded, no search query is logged, no data touches a server. This is not a policy promise, it is an architectural fact you can verify by opening DevTools' Network tab while you use the tool, or by pulling your Wi-Fi and watching it keep working.
That matters more than it sounds. Most CSV files worth looking at contain something you would not paste into a stranger's website: customer emails, payroll figures, order histories, an export from a production database. If you work under GDPR, HIPAA, or a client NDA, "I pasted it into an online converter" is not a sentence you want to say out loud. I wrote more about that threat model in why client-side tools beat cloud converters.
How to use the CSV Viewer
Step 1: Load the file
Two ways in. Paste the CSV text straight into the input box โ good for a snippet from a log, a Slack message, or an API response you want to eyeball. Or click Upload File and pick a .csv, .tsv, or .txt file from your machine. The file is read locally; the upload button is a file picker, not an upload.
If you are pasting from a spreadsheet, note that most spreadsheet applications put tab-separated text on the clipboard, not commas. Set the delimiter to Tab, or leave it on Auto and let detection handle it.
Step 2: Check the parse settings
Three settings, and the defaults are right most of the time.
Delimiter is Auto by default. Override it if your file has one column, or if detection guesses wrong on a small sample.
First row is header is on. Turn it off for headerless files โ the columns become Column 1, Column 2, and so on, and no row is consumed.
Trim whitespace is on, which strips leading and trailing spaces from every cell. This is usually what you want, since , after a delimiter is extremely common in hand-written CSVs. Turn it off if your data has meaningful leading spaces, such as fixed-width fields that were dumped to CSV.
Step 3: Read the table
Hit View as Table and you get the parsed grid plus a stats line: how many rows are visible out of how many total, how many columns, which delimiter was used, and how many columns are fully numeric. That numeric count is a fast sanity check โ if a column you expect to be numeric is not counted, some row in it holds a non-number, and it is usually the row that will break your import.
Search filters rows. Clicking a header sorts. The two compose.
Step 4: Export or move on
Copy the visible table as JSON, download it as CSV, or download it as JSON. Filters and sorting are applied to the export, so "search for refunded, sort by date, download CSV" gives you exactly that subset.
How does this compare to other ways of opening a CSV?
| Approach | Coerces your data | Handles quoted fields | Works offline | Sends data anywhere | Good for |
|---|---|---|---|---|---|
| CSV Viewer (toolz.dev) | No | Yes (RFC 4180) | Yes | No | Inspecting, searching, sanity-checking, converting to JSON |
| Excel / Google Sheets | Yes โ dates, leading zeros, scientific notation | Yes | Excel yes, Sheets no | Sheets uploads to Google | Editing, formulas, charts |
| A text editor | No | No โ you parse it in your head | Yes | No | Tiny files, checking line endings |
csvkit / xsv / DuckDB CLI |
No | Yes | Yes | No | Huge files, scripting, joins, aggregation |
pandas read_csv |
Yes, by default (dtype=str to stop it) |
Yes | Yes | No | Analysis, transformation pipelines |
| Most "online CSV viewer" sites | Varies | Usually | No | Yes โ uploaded to their server | Nothing you care about |
The honest summary: for files above a few hundred megabytes, use DuckDB or xsv โ a browser parses the whole file into memory in one pass and there is no way around that. For anything you need to edit with formulas, use a spreadsheet and accept the coercion, or import as text. For everything in between โ the daily "what is actually in this file, and why did row 4,201 break" โ a viewer that changes nothing is the right tool.
Common use cases
Debugging a failed import
A CSV import fails with "expected 8 columns, got 9 on line 4201". Open the file in the viewer, check the ragged-row warning, then search for a value you know is on that record. Nine times out of ten you will find an unquoted comma inside an address or a company name โ Acme, Inc. written without quotes. Now you know whether to fix the export or pre-process the file.
Reviewing a database export before it goes anywhere
Before a client's data leaves your laptop, you want to know what is in it. Column names, row count, whether the email column is fully populated, whether there are duplicate IDs. The stats line and column filled/unique counts answer all of that in about ten seconds, without the file ever reaching a server.
Converting CSV to JSON for an API or a script
You have a spreadsheet of records and you need them as JSON to seed a database, feed a REST endpoint, or build a fixture file. Paste, parse, export JSON. If you need the reverse trip, the CSV to JSON and JSON to CSV tools handle dedicated conversion with more options, and I walked through the round-trip problem in detail in the JSON to CSV conversion guide.
Checking a European export that opened as one column
A client sends an export from a German Excel install and every row is one long string. Set the delimiter to Semicolon and it snaps into columns. This takes four seconds and is worth knowing about, because the reflex "the file is corrupt" is wrong โ the file is fine, your parser's assumption was not.
Auditing analytics or ad platform exports
GA4, Google Ads, and Meta exports arrive as CSV with metadata rows above the actual header. Turn off "First row is header", look at the shape, and you will see exactly which line the real header sits on โ then delete the junk lines from the paste box and re-parse.
Technical deep dive: the parsing rules that actually matter
RFC 4180 is a description, not a standard anyone enforces. It was published in 2005 to document what CSV implementations already did, and it explicitly notes that many differ. Treat it as the sane baseline, not as a guarantee about a file you were sent.
Quoting rules. A field may be wrapped in double quotes. Inside quotes, delimiters, CR, LF, and doubled quotes ("" โ ") are literal. A quote appearing in the middle of an unquoted field is ambiguous โ the viewer treats quoting as significant only when the quote is the first character of the field, which is how most real parsers behave and which lets values like 6" nails survive.
Line endings. CRLF is what the spec says. LF is what Unix produces. A bare CR is what very old Mac software produced and what a few embedded systems still produce. The parser accepts all three, including mixed endings within one file, because mixed endings absolutely happen when files get edited on two machines.
The BOM. UTF-8 files written by Excel begin with a byte-order mark, EF BB BF. If your first column name looks like id but a string comparison against "id" fails, that invisible BOM is riding on the front of it. This is the single most common "why does my header lookup fail" bug in CSV handling.
Trailing newlines. A file ending with a newline does not have an extra empty record โ the newline terminates the last record. The viewer's skip-empty-lines option makes this a non-issue either way.
Type inference. There isn't any. CSV has no types. Every value in the file is a string, and any type you get out the other side was invented by your parser based on a guess. This is not a flaw in the format, it is the format's entire nature โ and it is why the viewer never guesses on your behalf.
FAQ
How do I open a CSV file without Excel?
Upload the file to the CSV Viewer or paste its contents into the input box. The file is parsed in your browser and displayed as a table you can search and sort. No spreadsheet software, no installation, and no upload to a server.
Why does my CSV open as one long column?
The delimiter does not match. Files exported in locales that use a comma as the decimal separator typically use semicolons between fields, and tab-separated exports use tabs. Switch the Delimiter setting from Auto to Semicolon, Tab, or Pipe and the columns will split correctly.
Does the viewer handle commas inside quoted fields?
Yes. The parser follows RFC 4180: a field wrapped in double quotes can contain delimiters, line breaks, and escaped quotes written as two double quotes in a row. A value like "Smith, John" stays in one cell instead of splitting into two.
What is the difference between CSV and TSV?
They use different field separators โ CSV separates with commas, TSV with tab characters. TSV needs less quoting because tabs rarely occur inside data values, which is why database and analytics exports often prefer it. This viewer reads both; pick Tab as the delimiter for TSV files.
What does the "ragged rows" warning mean?
A row has more or fewer fields than the header row. It usually means an unquoted delimiter inside a value, a truncated export, or a field containing a stray line break. The viewer pads short rows and truncates long ones so the table still renders, and tells you how many rows were affected.
Is there a file size limit?
The practical limit is your browser memory, since the entire file is parsed in a single JavaScript pass. Files up to a few tens of megabytes are fine on a typical laptop. For multi-gigabyte exports, use a streaming tool such as csvkit, DuckDB, or pandas with chunksize instead.
Can I convert the CSV to JSON?
Yes. The Export panel converts the parsed table to an array of JSON objects keyed by the header row, which you can copy or download. Values stay as strings by design โ coercing them to numbers would strip leading zeros from IDs, ZIP codes, and phone numbers.
Is it safe to open a confidential CSV here?
Yes. Parsing runs entirely in your browser using JavaScript and the FileReader API. No file, cell, or search query is transmitted to a server or logged. You can verify this by opening your browser DevTools Network tab while using the tool, or by disconnecting from the internet.
Related tools
- CSV to JSON โ dedicated conversion with type options
- JSON to CSV โ the return trip, including nested object flattening
- XML to JSON โ for the exports that arrive as XML instead
- JSON Formatter โ clean up the JSON you just exported
- JSON Diff โ compare two exports and find what changed
Further reading: The Ultimate Guide to JSON Tools and JSON to CSV Conversion.
