The Complete Guide to CSV Files and Formatting
CSV is the format everything speaks and nobody agrees on. Every database, spreadsheet, analytics platform, and billing system can import and export it, which is exactly why it has survived fifty years of formats designed to replace it. It is also why so many CSV files arrive slightly wrong: shifted columns, mangled accents, a delimiter you did not expect, a phone number that lost its leading zero somewhere between the export and your inbox.
This guide covers what a CSV file actually is, the rules that govern it, the places where real-world files break those rules, and the practices that keep your own exports readable by whoever receives them.
What a CSV file actually is
A CSV file is plain text. Open it in any text editor and you see everything there is:
id,name,email,signup_date
1,Ada Lovelace,ada@example.com,2026-01-14
2,Grace Hopper,grace@example.com,2026-02-03
Each line is a record. Within a line, a delimiter separates fields. That is the whole model. There are no cell types, no formulas, no bold text, no column widths, no second sheet. A CSV does not know that signup_date holds dates or that id holds integers — every value is a string until a consumer decides otherwise, and that decision is where most CSV problems begin.
The upside of this poverty is durability. A CSV written in 1990 opens today. It streams line by line, so a program can process a file larger than its memory. It diffs cleanly in version control. It has no dependencies, no library, and no version number to negotiate. When you need data to cross a boundary between two systems that share nothing else, CSV is usually the answer.
The rules RFC 4180 defines
CSV predates any attempt to specify it. RFC 4180 was published in 2005 to describe what most implementations already did, and it is best understood as a common convention rather than a standard that anything is obliged to follow. It is still the right target when you write a file, because it is the behaviour parsers are most likely to expect.
The core rules:
Records are separated by CRLF. The specification calls for a carriage return plus line feed (\r\n) between records, with the final record's line break optional. In practice, Unix-born tools emit bare LF and virtually every parser accepts both.
Fields are separated by commas. Hence the name. Leading and trailing spaces around a field are part of the field, not decoration to be trimmed.
A header row is optional. RFC 4180 allows an initial line of column names and defines a header MIME parameter to declare its presence, but nothing in the file itself marks it. A parser cannot tell a header from a data row.
Fields may be enclosed in double quotes. Quoting is always allowed and sometimes required.
Quoting is mandatory when the field contains a comma, a double quote, or a line break. These are the three characters that would otherwise be structural. A field containing any of them must be wrapped.
A literal double quote inside a quoted field is escaped by doubling it. Not with a backslash — CSV has no backslash escaping at all. This trips up people arriving from JSON or C-like languages more than any other rule.
Put together:
sku,description,notes
A-100,"Bracket, 20mm","Fits 3/4"" pipe"
A-101,"Multi-line
description here",
Row two has a comma inside description, so it is quoted. The notes field contains a literal " after 3/4, so it is quoted and the inner quote is doubled. Row three contains an actual line break inside a quoted field — which is legal, and which is why you cannot parse CSV by splitting on newlines.
That last point deserves emphasis, because it is the single most common bug in hand-rolled CSV handling. text.split("\n") and line.split(",") are wrong for any file containing quoted fields. Use a real parser.
Where real files diverge
RFC 4180 describes a convention; the files that land in your inbox describe reality. These are the deviations you should expect.
Different delimiters
The comma is the default, but it is far from universal. In locales where the comma is the decimal separator — most of continental Europe, much of South America — spreadsheet applications export with a semicolon instead, because 1,50 is a number and cannot also be a field boundary. Tab-separated values (TSV) sidestep the problem entirely, since tabs almost never appear in ordinary text. Pipe-delimited files show up in legacy banking and telecom feeds for the same reason.
All of these are commonly filed under "CSV". Detection is usually a matter of counting candidate characters per line and picking the one with a consistent count. Our guide to CSV delimiters covers detection and conversion in detail.
Line endings and encoding
Files move between Windows, macOS, and Linux and pick up mixed line endings on the way. Most parsers cope; some legacy Windows tools require CRLF.
Encoding is the more damaging axis. UTF-8 is the correct choice and the modern default, but files still arrive as Windows-1252 or ISO-8859-1, and reading one as the other turns café into café. There is no encoding declaration inside a CSV file — nothing analogous to an XML declaration — so it is either agreed out of band or guessed. The one hint available is a UTF-8 byte order mark, three bytes at the start of the file, which Excel on Windows uses to recognise UTF-8 on a double-click. It is ugly and technically discouraged, but it is the difference between a readable file and a corrupted one for a large population of recipients.
Structural sloppiness
Ragged rows — records with more or fewer fields than the header — are common in files assembled by concatenation or edited by hand. Some exporters emit blank lines between records. Some prepend comment lines starting with #, which RFC 4180 does not sanction and most parsers do not recognise. Some quote every field regardless of need, which is harmless. Some quote none, which is not.
When a file is misbehaving and you cannot see why, running it through a CSV Validator is faster than reading it. It reports the row and column of the first structural break, which is nearly always more useful than a parser's generic "unexpected token" complaint. The full repair walkthrough covers what to do once you know where the break is.
Type inference: the silent data loss
A CSV holds text. A spreadsheet wants types. The conversion between them is guesswork, and the guesses are lossy.
Excel is the best-known offender because it is the most-used consumer. Open a CSV containing a postal code of 01234 and Excel decides it is the number 1234. Open one containing 1-2 and it becomes 2 January. A 16-digit order reference becomes 1.23457E+15, and the trailing digits are not hidden — they are gone. Save the file and those transformations are written back to disk permanently.
Nothing in the CSV can prevent this, because CSV has no way to say "this column is text". Prefixing values with an apostrophe or wrapping them in quotes does not help; quoting is a structural device, not a type annotation, and Excel ignores it for this purpose. The only reliable defence is to import rather than open — Data → From Text/CSV, then set the affected columns to Text before loading. We cover Excel's specific CSV failures and how to work around each one separately.
The general lesson applies beyond Excel: whenever a CSV crosses into a typed system, someone is inferring types, and identifiers that look like numbers are the values most likely to be damaged.
Writing a CSV people can read
If you control the export, a handful of decisions prevent most downstream complaints.
Always write a header row. It is the only documentation a CSV can carry. Keep names lowercase, ASCII, and free of spaces — order_total, not Order Total ($). Names without spaces survive being loaded into a database or dataframe without renaming.
Use UTF-8, and add a BOM only if Excel double-clicks are expected. Pick one and state it in whatever documentation accompanies the file.
Quote defensively. Quoting every field, or every non-numeric field, costs a few bytes and eliminates an entire class of failure. Never emit an unquoted field containing your delimiter.
Use ISO 8601 dates. 2026-08-06 is unambiguous. 06/08/2026 means August in one country and June in another, and no parser can tell which without being told.
Keep one record per row and one meaning per column. A cell containing admin;billing is a nested list smuggled into a flat format. Sometimes unavoidable, but flag it in the column name.
Do not mix data and presentation. No totals row at the bottom, no blank spacer rows, no merged-looking headers spread over two lines. A CSV is a data interchange file, not a report.
Be consistent about empty versus null. CSV cannot distinguish them. Pick empty-string-for-null, and never write the literal text NULL unless the recipient has agreed to it.
An easy way to check your output against these habits is to paste it into a CSV Formatter, which normalises quoting, delimiters, and line endings and shows you the parsed shape rather than the raw text.
CSV, Excel, and JSON: choosing a format
CSV is right for tabular data moving between systems, for anything that needs to stream, and for files that belong in version control. It is wrong when you need multiple sheets, formulas, cell formatting, or reliable types — that is what XLSX exists for, and the CSV versus Excel comparison covers the trade-off in full.
CSV is also wrong for hierarchical data. A CSV is a rectangle; nested objects and arrays have to be flattened into it, and the flattening is a design decision with real consequences. When the destination is an API or a config file, converting to JSON is usually better than forcing structure into columns.
For genuinely large analytical datasets, columnar formats like Parquet beat CSV on size and read speed by an order of magnitude. CSV's advantage is that everything can read it, and that advantage is worth a lot until the file stops fitting in memory.
Handling files that are too big
The format streams; the tools often do not. Excel caps out at 1,048,576 rows, and a browser tab will run out of memory long before a well-written command-line tool does.
Three approaches, in increasing order of effort. Split the file into row-bounded chunks — the right answer for import limits and for sharing samples, and the subject of our guide to splitting large CSVs. Stream it, processing row by row with a parser that never holds the whole file, which is what csv in Python, csvkit, or DuckDB do. Load it into a database and stop treating it as a file at all, which is where any recurring pipeline eventually ends up.
The reverse problem — many small files that need to become one — has its own set of traps around mismatched headers and column order, covered in merging CSV files without losing rows.
Inspecting an unfamiliar file
When a CSV arrives from outside, four questions determine everything that follows: what is the delimiter, what is the encoding, does it have a header, and are the rows consistent? Answer them before writing any code against the file.
A quick pass through a CSV Analyzer answers all four at once — it reports the detected delimiter, column count, per-column inferred types, null counts, and any rows whose field count disagrees with the header. Because it runs entirely in your browser, the file never leaves your machine, which matters given how often the CSVs people need to inspect are customer lists, payroll extracts, or transaction exports.
Conclusion
CSV's weakness and its strength are the same thing: it specifies almost nothing. There are no types, no encoding declaration, no schema, and no enforced delimiter, which is why it interoperates with everything and why it breaks in a dozen predictable ways.
Working with it well comes down to a short discipline. Follow RFC 4180 when you write — quote anything containing a delimiter, quote, or newline, double your inner quotes, emit UTF-8 and a header row and ISO dates. Assume nothing when you read — check the delimiter, check the encoding, check for ragged rows, and never let a spreadsheet guess types on a column of identifiers. Use a real parser rather than splitting on commas, because quoted fields containing newlines are legal and will find you eventually.
Do that and CSV stops being the format that quietly corrupts your data and goes back to being the one that just works everywhere.
Frequently asked questions
What is a CSV file?
A CSV file is plain text holding tabular data: one record per line, fields separated by a delimiter, usually a comma. It carries no formatting, formulas, colours, or multiple sheets — only values and, by convention, a header row naming the columns.
Is CSV an official standard?
Not in the way JSON or XML are. RFC 4180 documents the most common convention and is what most tools aim at, but it was published in 2005 to describe existing practice rather than to mandate it. Files that violate it are still routinely produced and accepted.
How do you put a comma inside a CSV field?
Wrap the whole field in double quotes: Smith, John becomes "Smith, John". The same applies to fields containing a double quote or a line break. A literal double quote inside a quoted field is written twice, so 5" becomes "5""".
Why does my CSV use semicolons instead of commas?
Because it was exported in a locale where the comma is the decimal separator. Excel and other spreadsheet apps follow the system list separator, which is a semicolon across much of Europe, so the same export produces a different delimiter depending on the machine that made it.
Does a CSV file need a header row?
No — RFC 4180 makes the header optional, and a parser cannot detect one reliably. Include it anyway. Column names are the only self-description a CSV has, and without them every consumer has to hard-code column positions.
What encoding should a CSV file use?
UTF-8. It handles every script and is the default assumption of nearly all modern tools. If the file will be double-clicked open in Excel on Windows, adding a UTF-8 BOM is the pragmatic exception that stops accented characters turning into mojibake.
Can Excel damage a CSV file just by opening it?
Opening alone is harmless; saving after opening is not. Excel strips leading zeros from numeric-looking text, reinterprets date-like strings, and converts long IDs to scientific notation. Save the file and those guesses are written back permanently.
How large can a CSV file be?
The format itself has no limit — CSVs of hundreds of gigabytes exist. The limits are in the tools. Excel stops at 1,048,576 rows, and browser-based editors are bounded by available memory, which is why very large files are usually split or streamed rather than opened.
Try the related tools
CSV to JSON Converter
Convert CSV rows into an array of JSON objects with type inference.
CSV Formatter & Beautifier
Format and align CSV columns with consistent delimiters and quoting.
CSV Validator
Validate CSV data integrity, column count consistency, and quoting rules.
CSV Analyzer & Column Inspector
Inspect column data types, unique values, null counts, and row statistics.
Related articles
CSV vs Excel: What's the Real Difference?
CSV vs Excel explained: what XLSX stores that plain text cannot, when each format is the right choice, and how to move data between them without losing anything.
How to Fix a Broken CSV File
Fix broken CSV files fast: diagnose quoting errors, ragged rows, stray line breaks and encoding damage, then repair them in the browser without uploading data.