toolhq.io

All posts
July 14, 20265 min read

Convert CSV to JSON: headers to keys, rows to objects

You have a CSV, an export from a spreadsheet, a database dump, a report someone emailed you, and the code that needs it wants JSON. The conversion is mechanical once you know the mapping, but CSV has just enough edge cases that a naive split on commas will eventually produce garbage. Paste the file into the JSON ↔ CSV Converter and it handles quoted fields and nested values in your browser, with nothing uploaded.

How the mapping works

The standard shape is simple:

  • The header row becomes the object keys.
  • Each data row becomes one object, with values matched to headers by position.
  • The whole file becomes an array of those objects.

A concrete example. This CSV:

name,role,logins
Ada,admin,3
Grace,editor,0

becomes this JSON:

[
  { "name": "Ada", "role": "admin", "logins": 3 },
  { "name": "Grace", "role": "editor", "logins": 0 }
]

Three columns, two data rows, so an array of two objects with three keys each. Every consumer that expects "an array of records" can take it from here.

Everything in a CSV is text

CSV has no type system. The cell 3 is the string "3" until something decides otherwise. A converter has two honest options: keep every value a string, or infer types by pattern, turning 3 into the number 3, true into a boolean, and so on.

Inference is usually what you want, but it can be wrong. Zip codes like 01230 lose their leading zero as numbers. A product ID of 12e5 is not scientific notation. Long numeric IDs can exceed what a JavaScript number stores exactly. Quoting in the source is the signal worth respecting: a cell written as "3" in the CSV was quoted on purpose and should stay a string. If your data has ID-like columns, check them after conversion and keep them as strings when in doubt.

The cases that break naive parsers

If you have ever converted CSV with line.split(","), these are the rows that punished you:

  • Commas inside quoted fields. "Smith, Jane",editor is two fields, not three. A real parser tracks quote state; a split does not.
  • Newlines inside quoted fields. A quoted cell can legally contain a line break, so one record can span multiple physical lines. Splitting the file on newlines first silently corrupts these rows.
  • Empty cells. Should a blank cell become null or ""? There is no universal answer. null is usually right for missing data, "" for genuinely empty text. Pick one deliberately and make sure your consumer agrees.
  • Duplicate headers. Two columns both named id collide as object keys, and one value overwrites the other. Rename them before converting, or expect data loss.
  • The BOM. Excel exports often start with an invisible byte order mark. Left in place, it glues itself to the first header, so your objects have a key that looks like name but is actually name and every lookup misses.

When JSON is the better shape

CSV is the right format for spreadsheets and bulk imports, but JSON wins the moment structure or code enters the picture. APIs expect JSON bodies. Config files want nesting that CSV cannot express. In JavaScript, an array of objects is directly usable: users.filter(u => u.role === "admin") works the second the conversion finishes, with no parsing layer in your own code. If the data ends its journey in a program rather than a grid, convert it once at the boundary and work with real types from then on.

Going the other way, when you have JSON and the destination is a spreadsheet, JSON to CSV: turn an API response into a spreadsheet covers that direction, including how nested values flatten into columns.