CSV to JSON Converter
Convert a CSV file into a JSON array of objects, keyed by your headers. Runs in your browser — no upload, no signup.
Drop your file here
Accepts CSV · Runs in your browser. Your file never leaves your device.
Most CSVs end up needing to be JSON eventually — to seed a database, mock an API, feed a frontend, or hand to whatever tool only speaks JSON. This converter does that one job and does it predictably: each row in the CSV becomes one object in a JSON array, with the header row as the keys. No nesting tricks, no schema-guessing, no surprises.
Output is pretty-printed JSON (indented two spaces) so it's diff-friendly and readable. The same parser SheetCompare uses for spreadsheet diffs reads your CSV, so quoting, escaping, and edge cases like embedded newlines work correctly. Everything happens client-side — your file is never uploaded.
Three steps, no signup
- 1
Drop your CSV
Drag a .csv file into the box above, or click to pick one. Files with quoted fields, embedded newlines, and UTF-8 content all work.
- 2
We map rows to objects
Row 1 becomes your JSON object keys. Each subsequent row becomes one object in the output array. Cell values come through as strings — no aggressive type-guessing.
- 3
Download the .json
Download a pretty-printed JSON array. Drop it straight into your code, paste it into a seed file, or hand it to your API.
Frequently asked questions
- What does the output JSON look like?
- A JSON array of objects. If your CSV has columns `name,email,age`, you get `[{"name": "...", "email": "...", "age": "..."}, ...]`. Pretty-printed with two-space indentation. Not NDJSON (newline-delimited) — if you need that, paste the array into `jq -c '.[]'` or similar after downloading.
- Are numbers and booleans converted, or do I get strings?
- You get strings. CSV has no type system — "123" and "true" are just text in the source file, and we don't guess. This is intentional: silent type coercion is the single biggest source of CSV-to-JSON bugs (zip codes losing leading zeros, account numbers becoming floats, the string "NaN" turning into a number). Cast types in your code where you actually know the schema.
- How are empty cells represented?
- As empty strings (`""`), not as `null`. The CSV spec doesn't distinguish between "no value" and "empty string," so we don't either — preserving the source verbatim is safer than guessing intent. If you need `null` for empties, run the output through a quick `JSON.stringify(JSON.parse(json), (k, v) => v === "" ? null : v)` after downloading.
- What if my CSV has no header row?
- The first data row is treated as the header row and consumed as keys. If you don't want that, add a synthetic header row (`col1,col2,col3,...`) before converting. CSV without headers is ambiguous — there's no way for a tool to know the difference between "row of data that looks like headers" and "actual headers."
- What happens with duplicate header names?
- Later columns with duplicate names overwrite earlier ones in each row's object — that's how JavaScript objects work, and we don't try to disambiguate. If your CSV has two columns both named `id`, only the rightmost `id` value will be in the output. Rename the duplicate columns in your source before converting if you need them both.
- Can I get nested JSON instead of a flat array?
- Not from this tool. CSV is fundamentally tabular — it has no way to express nesting — so any nesting we produced would be guesswork (split by dot? underscore? bracket?). For nested output, post-process the flat array in your code where you know the schema, or use a tool purpose-built for hierarchical CSV like csvjson with explicit options.
- What encoding is the output?
- UTF-8. JSON is required by spec to be Unicode (UTF-8 is the standard transport encoding), so non-ASCII characters in your CSV — accented letters, CJK, emoji — pass through cleanly. The downloaded file has no BOM.