Paste some CSV to see the JSON keys it produces.
Need the reverse? JSON to CSV Converter

About the CSV to JSON Converter

What is a CSV to JSON converter?

A CSV file is a grid. JSON is a set of records. A CSV to JSON converter reads the grid, takes the first row as the key names, and writes every following row as an object using those keys. That is the format APIs, JavaScript apps, test fixtures and document databases all want, and it is the format spreadsheets never produce.

The reading part is where most tools quietly go wrong. A value wrapped in quotes can contain the delimiter, a line break, or an escaped quote of its own, and each of those has to survive the trip intact. We tested the popular converters against a file holding all three, and most of them shifted columns, dropped characters, or split one row into two. This one follows RFC 4180 and gives you the same values you started with.

How to Use This Tool

  1. Paste your CSV. Drop a file onto the box or use Open file if it is large. Tabs, semicolons and pipes are picked up without being told.
  2. Check the field map. The strip below the boxes names every JSON key the converter built and the type it will write into it.
  3. Pick the output shape. An array of objects suits most work. Keyed output gives you a lookup table, and NDJSON is what bulk loaders expect.
  4. Tune the reading if a value looks wrong. Turn off number detection to keep everything as text, name the words that should read as null, or trim the stray spaces an export left behind.
  5. Copy or download. Nothing is uploaded, so there is no size tier and no sign-up.

Example

With the default options (array of objects, 2 space indentation, numbers and booleans detected), this CSV will be converted to a JSON array of two records:

Input: CSV
name,active,zip
"Lovelace, Ada",true,007
Grace Hopper,false,10001
Output: JSON
[
  {
    "name": "Lovelace, Ada",
    "active": true,
    "zip": "007"
  },
  {
    "name": "Grace Hopper",
    "active": false,
    "zip": "10001"
  }
]

Three things happened there. The comma inside the quoted name stayed put instead of splitting the row. true and false became real booleans. And 007 kept its leading zeros, which also kept 10001 as text so the whole zip column reads the same way. Switch Output shape to NDJSON and the same input gives you one compact record per line instead.

Choosing the output shape

Five shapes cover almost everything people need from the same file. Pick the one your destination is expecting:

ShapeLooks likeGood for
Array of objects[{"name":"Ada"}]APIs, fixtures, MongoDB, most JavaScript
Array of arrays[["name"],["Ada"]]Charting libraries and Google Sheets
One array per column{"name":["Ada"]}Pandas, plotting, column stores
Keyed by a column{"Ada":{"active":true}}Lookup tables and config files
NDJSONone record per lineElasticsearch bulk loads, BigQuery, log pipelines

Keyed output uses the first column by default and you can point it at any other one. The column you key on is not repeated inside each record, since it is already the key. If two rows share a value there, the later row wins and the notes panel tells you it happened.

How values get their type

Turning 42 into a number is easy. Deciding what to do with 007, 1e5 and a nineteen digit account number is where converters lose data, usually silently. Two rules keep that from happening here.

First, a value only becomes a number when writing it back out gives you the exact same characters. 42 survives that test. 007 does not, because it would come back as 7. Neither does a nineteen digit ID, because JavaScript numbers run out of precision before then and it would come back with the last digits changed. Those stay as text, with every character intact.

Second, the decision is made once per column rather than once per cell. If a single value in a column fails the test, the whole column stays text. That is why the zip column in the example above is all strings and not a mix of "007" and 10001, which is what every other converter we tested produces. A stable type per key is what anything reading the JSON afterward actually needs.

CellBecomesWhy
4242Round trips exactly
10.5010.5Same value, the trailing zero is formatting
007"007"The leading zeros are part of the code
1,5"1,5"A European decimal is not a JSON number
TRUEtrueBooleans are matched whatever the case
9007199254740993"9007199254740993"Past the precision limit, so it would change

If you would rather have everything as text, turn off Detect numbers and Detect true and false. To make words like NULL or N/A come out as a real JSON null, list them in Read as null.

Reading the field map

The strip between the boxes names every key the JSON will carry and the type going into it. Keys come from the header row after the converter has trimmed them and made them unique, so if two columns were both called id you will see id and id_2 and know which is which. It is the fastest way to catch a header row that picked up a stray column or a spreadsheet that exported an unnamed one.

A card that reads 4 of 30 means that column is empty in most rows. Sometimes that is the data, and sometimes it is a sign the delimiter guess was wrong and the values landed in the wrong place. Either way it is better to see it now than after the import.

Rows that do not line up

Exports from older systems are rarely rectangular. A row can run short because a trailing value was empty, or run long because someone typed a comma into a field. Most converters either drop the row without saying anything or refuse the whole file. This one keeps going and tells you which lines were odd, by number.

Short rows get empty values for the missing keys. Long rows keep their extra values under generated names like column_4, so nothing disappears. If you would rather not have those, Rows that do not line up can drop the extras or skip the row entirely. Either way the notes panel names the lines so you can go and look at the source.

Semicolon, tab and pipe separated files

Excel in most of Europe writes semicolons instead of commas, because the comma is already busy being a decimal point. Tab separated exports come out of databases and old reporting tools. Both are read here without changing a setting, along with pipes and colons, because the delimiter is worked out by parsing the first few dozen lines with each candidate and keeping the one that gives a consistent column count. The result is shown next to the row count so you can confirm it guessed right, and the Delimiter menu overrides it if it did not.

Converting CSV to JSON in code

For a repeatable job you want this in a script. Python has a CSV reader in the standard library, and DictReader already produces dictionaries:

Python
import csv, json

with open('data.csv', newline='', encoding='utf-8-sig') as f:
    rows = list(csv.DictReader(f))

with open('data.json', 'w') as out:
    json.dump(rows, out, indent=2)

The utf-8-sig encoding matters more than it looks. It strips the byte order mark Excel writes, which otherwise ends up glued to your first key name.

JavaScript, Node.js
import { parse } from 'csv-parse/sync';
import fs from 'node:fs';

const rows = parse(fs.readFileSync('data.csv'), {
    columns: true,
    skip_empty_lines: true,
    bom: true
});

fs.writeFileSync('data.json', JSON.stringify(rows, null, 2));

PHP reads a row at a time with fgetcsv, so you pair the header row with each line yourself:

PHP
<?php
$in = fopen('data.csv', 'r');
$keys = fgetcsv($in);
$rows = [];
while (($row = fgetcsv($in)) !== false) {
    $rows[] = array_combine($keys, $row);
}
fclose($in);
file_put_contents('data.json', json_encode($rows, JSON_PRETTY_PRINT));

All three keep every value as text. Type detection, uneven rows and duplicate headers are yours to handle, which is most of what the tool above is doing for you.

Common Use Cases

The conversion usually shows up at the seam between a spreadsheet and some code. The jobs we see most:

  • Seeding an app with real data: a client sends a spreadsheet, your app wants JSON.
  • Test fixtures: keeping sample data in a sheet is easier to edit than keeping it in a code file.
  • Feeding an API: most endpoints take a JSON body, and almost none take CSV.
  • MongoDB and Elasticsearch imports: both prefer NDJSON for bulk loading.
  • Charts and dashboards: plotting libraries usually want arrays of objects or one array per column.
  • Config and lookup tables: keyed output turns a two column sheet into a map you can drop into an app.

Going the other way? The JSON to CSV Converter flattens records back into rows. Once you have the JSON, the JSON Formatter tidies the spacing, the JSON Validator confirms it parses, and the JSON Viewer gives you a collapsible tree for a long file. To look at the CSV as a sortable table before converting it, open the CSV Viewer.

Frequently Asked Questions

How do I convert CSV to JSON?

Paste the CSV into the left box, or drop a file onto it. The JSON appears on the right straight away, keyed by your header row, and the Copy and Download buttons take it from there. Nothing is uploaded and there is no account to make.

Does it handle commas inside CSV fields?

Yes. A value wrapped in double quotes can hold commas, line breaks and quotes of its own, and all three come through unchanged. A quote inside a quoted value is written twice in CSV, so a doubled pair reads back as a single quote character. That case in particular breaks several of the better known converters.

Can I convert CSV to a JSON array?

Yes, and that is the default. Every row becomes an object inside one array, with the header row supplying the keys. If you need the plain grid instead, Array of arrays gives you the header as the first inner array and one array per row after it.

What happens if my CSV has inconsistent rows?

Nothing is lost and nothing fails. A short row gets empty values for the keys it is missing, and a long row keeps its extras under generated names like column_4. Either way the notes panel lists the line numbers so you can check the source, and the Rows that do not line up menu lets you drop or skip them instead.

Why does my zip code lose its leading zeros elsewhere but not here?

Because most converters test each cell on its own and turn anything that looks numeric into a number, which quietly rewrites 007 as 7. Here a value only becomes a number when it can be written back out identically, and the decision is made for the whole column at once. One code with a leading zero keeps the entire column as text.

Can it convert a semicolon separated file?

Yes, and it should pick that up on its own. The delimiter is worked out by parsing the start of your file with each candidate and keeping the one that gives a consistent column count. Tabs, pipes and colons are covered the same way, and you can always set it by hand.

How do I convert CSV to NDJSON or JSON Lines?

Set Output shape to NDJSON. You get one compact JSON object per line with no wrapping array and no commas between records, which is the format Elasticsearch bulk indexing, BigQuery loads and most log pipelines expect. JSONL and NDJSON are two names for the same thing.

Can I convert an Excel file to JSON?

Not directly, but the two step route is quick. In Excel or Google Sheets choose Save as or Download and pick CSV, then paste that here. Going through CSV also drops the formatting and formulas that would have no meaning in JSON anyway.

What happens to duplicate column names?

They are kept, not overwritten. JSON keys have to be unique, so a repeated header gets a numbered suffix and you end up with id and id_2. The notes panel says it happened. Several popular converters keep only the last of the matching columns and never mention the one they dropped.

Is my data sent to a server?

No. The converter is JavaScript running in your browser, so the CSV you paste never leaves your device. That is worth knowing when the file is a customer list or an export from a payroll system.