Skip to Content
RowSlice

Free Online CSV to JSON Converter

Convert a CSV to a JSON Array or NDJSON

You want JSON because the next thing along takes JSON: an API import, an n8n or Zapier step, a fixture for a test. This writes it straight from the text of the CSV, a row at a time, so the values arrive as the characters your file actually holds.

  • Array or NDJSON
  • Values kept as text
  • Never uploaded

In short: RowSlice's CSV to JSON converter turns each data row into one flat JSON object, in your browser, without the file being uploaded. You choose the shape — one array, or one object per line as NDJSON — and whether values are written as strings or as real JSON types. The default is strings, so 00742 stays 00742 and a 19-digit order number keeps all 19 digits. Empty cells can be written as "", as null, or left out of the object entirely. The CSV is read about 4 MB at a time and one row is held at a time, so a multi-gigabyte export converts the same way a small one does.

How to Convert a CSV to JSON

  1. Choose or drag in the CSV. It is read from your own disk rather than uploaded, so even a large file is ready in a second, and the first rows appear as a preview with the delimiter and encoding that were detected.
  2. Pick the shape: array for one JSON document, NDJSON for one object per line. The next section shows both from the same input.
  3. Leave Values on text unless the consumer needs real numbers. Text is what keeps identifiers intact.
  4. Decide what an empty cell should mean — "", null or a key that is not there — and press Convert to JSON.
  5. Download yourfile.json or yourfile.ndjson. The result says how many keys were written and how big the file is, so you can check the count against the columns your header had.

Array or NDJSON?

Both shapes come from the same reading of the file. This CSV:

order_id,sku,qty,ship_to_zip
1001,SEP-1,2,00742
1002,A-77,1,10013

becomes this as an array, with Pretty print on:

[
  {
    "order_id": "1001",
    "sku": "SEP-1",
    "qty": "2",
    "ship_to_zip": "00742"
  },
  {
    "order_id": "1002",
    "sku": "A-77",
    "qty": "1",
    "ship_to_zip": "10013"
  }
]

and this as NDJSON:

{"order_id":"1001","sku":"SEP-1","qty":"2","ship_to_zip":"00742"}
{"order_id":"1002","sku":"A-77","qty":"1","ship_to_zip":"10013"}

The array is a single document: a reader has to reach the closing bracket before it has anything. NDJSON is a file of independent objects, one per line, so a reader can act on the first record while the rest is still arriving, and a broken line is one broken record rather than a file that will not parse. NDJSON is never indented — indenting it would put one object across several lines and no NDJSON reader would find them.

ShapeWhat the file isPick it when
Array — .jsonOne document: [, the objects, ]A fetch then JSON.parse in a browser, a request body, a fixture checked into a repository, anything that wants one valid JSON value
NDJSON — .ndjsonOne object per line, no brackets, no commas between themA bulk-load endpoint, a queue producer, a shell loop over the file — anything that reads a record at a time and should not wait for the last byte

Turn Pretty print off and the array is the same document without the indentation. It still puts one object on each line, which is deliberate: a converted export ends up in an editor or a diff sooner or later, and a single ten-million-object line is neither readable nor openable. Pretty print does not apply to NDJSON, which is one object per line by definition.

Why Every Value Is a String by Default

A CSV records no types. 00742 is five characters, and the only thing that can be said about it with certainty is that it is those five characters. Writing it as a JSON number turns it into 742, and no later step can tell that a zip code was lost rather than a quantity written oddly. So text is the default, and in text mode every value in the file is written as a JSON string.

Auto is for the JSON you are going to do arithmetic on. It writes a value as a real JSON number only when writing it as a number and reading it back would give exactly the same text — the same test the CSV to Excel converter uses, and for the same reason. The same input as above, in auto mode:

{"order_id":1001,"sku":"SEP-1","qty":2,"ship_to_zip":"00742"}
{"order_id":1002,"sku":"A-77","qty":1,"ship_to_zip":"10013"}

order_id and qty are numbers now. ship_to_zip is still a string, in the same file, because the test runs on each value rather than on the column it sits in. Here is what auto mode refuses, and why:

In the CSVAuto mode writesWhy
12501250Reads back as the same text
-3.75-3.75Reads back as the same text
00742"00742"As a number it comes back 742
4532118899001234567"4532118899001234567"Past 15 significant digits a JSON number is a rounded double
0.50"0.50"Comes back 0.5; a price that changed is still a change
1e5"1e5"Comes back 100000
truetrueWritten as a boolean, in lower case only
TRUE"TRUE"A boolean here would come back as text the file never said
null"null"The word in a cell is the word, not an absent value

Those refusals are the feature, not a gap in it. Turning a long identifier into a rounded double is the loss that Excel is best known for, and JSON's numbers are the same double: RFC 8259, the JSON specification, notes that readers generally use IEEE 754 double precision, which holds 15 significant decimal digits exactly and rounds whatever comes after them. So the same care applies.

Empty Cells: "", null, or Left Out

An empty cell in a CSV means nothing in particular — it is a delimiter followed by another delimiter. What it should become in JSON depends entirely on what reads the JSON, so it is a setting rather than a guess. Given this row:

id,email,phone
7,ann@shop.com,

the three choices write, in order, an empty string, a null, and no key at all:

{"id":"7","email":"ann@shop.com","phone":""}
{"id":"7","email":"ann@shop.com","phone":null}
{"id":"7","email":"ann@shop.com"}

Empty string is the default and the most literal: it says the cell was there and held no characters.null is what most databases and schema validators mean by a missing value, and it is the one to pick when the JSON is going into a typed field. Omit leaves the key out, which is right for an API that treats a present key as an instruction to set that field — sending "" there would blank a value you meant to leave alone. The cost of omit is that objects stop having identical key sets, so code that loops over the rows has to cope with a missing key, and a row whose every value is empty comes out as {}. The other two modes always write every key.

How Large a CSV Can It Convert?

The converter never holds the document. The CSV is read about 4 MB at a time, one row is turned into one object and written out, and what stays in memory is a fixed structure per column — the key names — never one per row. A 40 GB file costs what a 40 KB one costs. The output goes to your browser's private on-disk storage (OPFS) as it is produced, not into a string that has to fit in the tab.

So the limit is disk, not memory, and the number to plan for is not the size of your CSV. JSON repeats every key on every row: a CSV writes order_id once and JSON writes it ten million times. Expect the output to be a multiple of the input, more so when the column names are long and the values are short, and keep that multiple inside the storage your browser gives one site — about 10 GB in Firefox. The written size is on the result before you download anything.

If you do not know how big the job is yet, the analyzer counts the rows and columns and reports the encoding and delimiter without writing a file, which is the cheapest way to size the conversion first. When the JSON is going into an import or an endpoint that has not taken it before, convert a sample of a few thousand rows and send that through first: finding out that the key names are wrong costs a second rather than a full conversion. And when only part of the export is wanted at the other end, cutting the CSV down to those rows first leaves fewer objects to write.

What It Does Not Do

It does not nest. A CSV is flat, so the JSON is flat: one object per row, one key per column, values that are strings, numbers or booleans and never objects or arrays. A column named address.city becomes a key with a dot in it, not a branch. Building a shape out of column names would mean inventing structure the file never recorded.

It does not infer a schema. There is no per-column type detection, no date parsing and nonull detection: the word null in a cell is the string "null", and 03/04/2026 is a string in every mode, because a CSV does not say whether that is April or March. Auto mode is the whole of the type conversion, and the table above is the whole of auto mode.

It reads CSV, not JSON. One file per run, in, and one file out. To go the other way — a JSON array or an NDJSON export into a spreadsheet-ready file — use the JSON to CSV converter, which flattens nested keys into dotted column names. To get a workbook instead of JSON, convert the CSV to .xlsx.

Last updated .

FAQ

Frequently Asked Questions

Does a ZIP code like 00742 keep its zeros in the JSON?

Yes, in both type modes. In text mode every value is written as a JSON string, so "00742" is what lands in the file. In auto mode a value whose leading zero would be lost is deliberately left as a string, because the number 742 is not the ZIP code your file holds. The same rule protects anything longer than 15 significant digits, which is where a JSON number — a double, like a cell in Excel — starts rounding. Stop Excel removing leading zeros from CSV files covers the same loss on the spreadsheet side.

What exactly does auto mode turn into a number?

A value becomes a JSON number only when writing it as a number and reading it back would give exactly the same text. 1250 and -3.75 pass. These do not, and stay strings: 00742 (the leading zero is lost), a 19-digit account number (past 15 significant digits), 0.50 (comes back as 0.5), -0 (comes back as 0), 1e5 and +5 (exponents and a leading plus are not written back the same way), and 1,200 or $12 (not numbers at all). Auto mode also writes the literals true and false, but only in lower case: TRUE would come back as text the file never said, so it stays the string "TRUE". The decision is taken value by value, not column by column.

Can I get nested JSON, with address.city as an object?

No. A CSV is a flat table, so the JSON is a flat object per row: every key is a column name and every value is a leaf. A column literally named address.city becomes a key with a dot in its name, not a nested object. Nesting would mean inventing a structure the file does not describe — which of first_name and billing_first_name belongs under what is a decision only you can make. Reshape the flat objects afterwards in whatever reads them; going the other way, the JSON to CSV converter does flatten nested keys, because there the structure is in the file rather than in a naming convention.

What happens to duplicate or empty column names?

An object cannot hold the same key twice, and an empty key reads as a missing one, so both are renamed. A header with email in two columns gives keys email and email_2, and a third would be email_3. A column whose name is empty or nothing but spaces is named for its position, counting from 1: the third column becomes column_3. Names are compared exactly, so ID and id are two different keys and both are written. The result says how many keys were written — one for every column, whatever the renaming did to the names. The validator flags duplicate and empty column names before you convert.

What about a row with more or fewer values than the header?

Neither stops the run. A row shorter than the header reads as empty in the columns it does not reach, so every object in the file carries the same keys — which is what any code looping over the result expects. A row with more values than the header has names gets keys for the extras, named by position: a fifth value under a four-column header becomes column_5, and from then on every object has that key. If ragged rows are a surprise rather than a plan, check the file first — it gives the data row number of every row with the wrong field count.

Should I choose the array or NDJSON?

Pick the array when whatever consumes it wants one document: a fetch in a browser followed by JSON.parse, a request body, a fixture checked into a repository. Pick NDJSON when the consumer reads a record at a time — a bulk-load endpoint, a queue producer, a shell loop over the file, anything that should start work on line one instead of after the last byte. For a file of any real size NDJSON is also the kinder shape to debug, because line 40,001 of the output is data row 40,001 of your CSV.

What encoding is the JSON, and does it have a byte order mark?

UTF-8, with LF line endings and never a byte order mark, whatever the CSV had. That is not a preference: a byte order mark is not whitespace to a JSON reader, so a mark at the top of the file makes JSON.parse and jq fail on the first character. The CSV itself can be in any encoding the tools read — if it is Windows-1252 or UTF-16 the characters are decoded and written out as correct UTF-8. What arrives already mangled in the CSV leaves mangled, so if accented letters look wrong in the preview, convert the file to UTF-8 first.

How large a CSV can it convert?

The CSV is read about 4 MB at a time and one row is held at a time, so memory does not grow with the file and there is no row limit. What limits the job is free disk space, inside the allowance your browser gives one site — about 10 GB in Firefox. Budget generously: JSON repeats every key on every row, so the output is normally several times the size of the CSV. A 500 MB export with eight short column names can comfortably pass a gigabyte. The size of the file that was written is shown with the result, before you download it.

Is my file uploaded anywhere?

No. The conversion runs in your browser, on your own computer, and the page keeps working with the connection switched off once it has loaded. There is no account and no copy on any server, which is the point when the CSV holds customer records or salaries. The JSON is written to your browser’s own private storage for this site until you download it and start a new job, and anything left behind is removed after six hours the next time you use a tool. Tested in current Chrome, Edge and Firefox on Windows; Safari and macOS are untested.

More Tools

More CSV Tools

CSV Analyzer

Count the rows, list the columns and profile the values in a CSV too big to open.

CSV Viewer

Page through and search a CSV that is far too large for Excel, without uploading it.

Compare Two CSV Files

See what was added, removed and changed between two exports, matched on an ID column.

Take a Sample from a CSV

Pull the first rows, every Nth row or a random slice out of a huge file for testing.

Sample CSV File Generator

Download realistic test CSV files from 10 rows up to 20 GB, with messy values on request.

Split CSV into Multiple Files

Cut a CSV that Excel refuses to open into multiple files by rows, size or number of parts.

Split CSV by Column Value

One file for every store, region, client or status — straight from a huge export.

Filter CSV Rows

Keep only the rows you need — by value, text match or number range — from a file of any size.

Merge CSV Files

Combine multiple CSV files into one, lining up columns by name, even when the result is too big for Excel.

Remove Duplicates from CSV

Delete repeated rows from millions of records, comparing whole rows or chosen columns.

Convert CSV to Excel

Make a real .xlsx file without losing leading zeros, long IDs or turning codes into dates.

Convert JSON to CSV

Flatten a JSON array or NDJSON export into a spreadsheet-ready CSV.

CSV Validator

Find the broken rows, bad quotes, wrong encoding and duplicate IDs before an import fails.

Convert CSV to UTF-8

Repair garbled characters like é by converting to UTF-8, and switch semicolons to commas.