Both formats look simple enough that people write their own converter. CSV in particular is where that goes wrong, because splitting on commas is correct for about 90% of real files.
CSV is not comma-separated
RFC 4180 defines a quoting mechanism, and any file containing free text will use it.
name,note
Ada,"Engineer, mathematician"
Grace,"She said ""hello"" first"
Alan,"Line one
line two"
Three things a naive split gets wrong here: the comma inside the quoted note, the doubled quotes representing a literal quote character, and the newline inside a quoted field, which means you cannot split the file into rows by line first.
A correct parser walks the file character by character tracking whether it is inside quotes. It is about thirty lines and worth using someone else's.
Free toolCSV to JSONTurn a CSV into an array of JSON objects in your browser, with proper handling of quoted fields, embedded commas and custom delimiters.The delimiter is not always a comma
Locales that use a comma as the decimal separator - most of continental Europe - export CSV with semicolons, because otherwise 1,5 is ambiguous.
This is why a French or German spreadsheet export opens as a single column in an English tool. The fix is choosing the right delimiter, not repairing the file. Tab-separated files sidestep the problem entirely and are worth preferring for anything internal.
Encoding
CSV carries no encoding declaration. Excel on Windows historically wrote them in the system codepage rather than UTF-8, which is why accented characters and emoji arrive as mojibake.
If a file must open cleanly by double-clicking in Excel, write UTF-8 with a byte order mark. If it is going to a script, write plain UTF-8 and open it in Excel through Data then From Text/CSV, where you can set the encoding explicitly.
Type coercion is where data dies
CSV has no types. Everything is text. A converter producing JSON has to decide whether 007 is a string or the number 7.
Guess numerically and you destroy:
- Zip codes:
01234becomes1234 - Phone numbers with leading zeros or a
+prefix - Product codes and account numbers with leading zeros
- Long IDs above 2^53, which lose precision as JavaScript floats
- Values like
1e5,NaNandInfinitythat were meant literally
Guess textually and every numeric column needs converting downstream.
There is no correct default, which is why any conversion of data that matters should be checked against the source. If you control the export, quote the columns that must stay text.
Nesting
JSON expresses hierarchy; CSV cannot. Converting JSON to CSV means one of three things:
Stringify the nested value into a cell. Preserves everything, unreadable in a spreadsheet.
Flatten with dotted keys, so user.address.city becomes a column. Works well for objects, badly for arrays of varying length.
Explode into multiple rows, one per array element, repeating the parent fields. This is what a database join produces and is usually what an analyst actually wants.
Pick deliberately. Silently stringifying is the default in most tools and the reason exports look fine and are useless.
Missing keys
When converting an array of objects to CSV, the header row is the union of every key across every object. An object missing a key gets an empty cell.
An empty cell is ambiguous: it could mean absent, empty string or null. If that distinction matters in your data, CSV is the wrong interchange format and you should be sending JSON Lines instead - one JSON object per line, which keeps types and nesting while staying streamable.
In a script
Python: csv.DictReader and json.dump for one direction, pandas.read_json and to_csv for the other. Node: csv-parse and json2csv. Command line: jq -r with @csv handles the JSON-to-CSV direction well.
For a one-off, use the CSV to JSON converter or the JSON to CSV converter - both parse quoted fields properly and run in the browser, so a customer export never leaves your machine.
