CSV to JSON Converter_

A spreadsheet file knows nothing about types. Every cell in a CSV is text, so turning one into JSON means deciding whether 007 is a number or a product code, and whether TRUE is a word or a boolean. This converter makes that decision yours, defaults to changing nothing, and prints what it read every column as — with a real value beside it — before you copy anything.

All of it happens in this tab. That is worth checking wherever you convert: search for the best-known alternatives and the results include other people's saved uploads, sitting at public URLs under titles like “GST Return” and “Annotations”.

toolkit.codes/csv-to-json

JSON
Nothing to convert yet
UTF-8
Ready
100% LOCAL

One row, every setting

SettingReading id,qty,ok / 007,2,TRUE
Text only (default)[{"id":"007","qty":"2","ok":"TRUE"}]
Safe types[{"id":"007","qty":2,"ok":true}] — the identifier is untouched
All types[{"id":7,"qty":2,"ok":true}]the leading zeros are gone
Output shape: keyed object, by id{"007":{"qty":"2","ok":"TRUE"}}
Output shape: array of arrays[["id","qty","ok"],["007","2","TRUE"]]
Output shape: JSON Lines{"id":"007","qty":"2","ok":"TRUE"} — one per line, no array
Pretty print offThe same JSON with no indentation or line breaks

Nothing above is a default you have to discover by reading the output. The mode is a control, and the table under the panes names what every column was read as.

Values that converters commonly mangle

Value in the CSVWhat a careless conversion givesHow to keep it
007 — a ZIP, SKU or account code7, and the zeros are unrecoverableText only or Safe types. Safe recognises leading zeros and leaves them alone
9007199254740993 — a database or Snowflake ID9007199254740992, silently off by oneText only or Safe types. Past 2⁵³ a JSON number cannot hold the value exactly
+44 20 7946 0958 — a phone numberUsually survives, but 0207946095 would notText only or Safe types; never All types for contact data
01/02/2026 — an ambiguous dateA string either way here, but Excel may already have rewritten itNothing is date-converted in any mode — JSON has no date type
TRUE, yes, Ntrue / false, including where the column meant a letter gradeText only, or check the type table before you commit
An empty cell"" here by default; some converters give nullThe Empty cells become null switch — it is a separate decision from number parsing

Every row here is a real report from the tools that get this wrong. The pattern is the same each time: a value that looks numeric but is an identifier.

What a CSV to JSON formatter is really deciding

Parsing is the easy half

Reading the file correctly is a solved problem with known traps: a comma inside a quoted field is data, not a separator; a line break inside quotes does not end the row; two quotes in a row mean one literal quote. Get those right and any CSV parses. None of that is where conversions go wrong.

Typing is the half that loses data

JSON distinguishes "7" from 7. CSV does not distinguish anything — it has no schema, no type row, nothing but characters between delimiters. So a converter has to guess, and a guess applied to a column of account numbers is how a file arrives at its destination looking right and being wrong. The default here is to guess nothing, because text is reversible: you can always parse "42" into a number afterwards, and there is no operation that recovers 007 from 7. Safe types exists because most people do want their quantity columns numeric, and it buys that without touching anything that reads like an identifier.

Converting CSV to JSON in Python

csv.DictReader(open("in.csv", newline="", encoding="utf-8-sig")) gives you dictionaries with every value as a string, which is the same conservative default as this page — then json.dump(list(reader), out, indent=2). The utf-8-sig matters: it strips the byte-order mark Excel writes, which otherwise ends up glued to your first column name. With pandas, pd.read_csv("in.csv", dtype=str) is the version that keeps your leading zeros; without dtype=str it will infer, and your ID column becomes integers.

Converting CSV to JSON in JavaScript

There is no CSV parser in the standard library, and the one-line split(",") answer is wrong for any file containing a quoted comma. Use a real parser — PapaParse in the browser or Node, with header: true and dynamicTyping left off unless you want the coercion described above. Java has the same story with Apache Commons CSV or Jackson's CSV module: the parsing is a library call, and the typing is a decision you still have to make.

How to use

  1. 01Paste or upload the file. The delimiter is detected and named on screen rather than silently chosen — if the detection is wrong, override it.
  2. 02Decide what the values are. This is the only step that can lose data: leave it on Text only to convert nothing, or move to Safe types to get numbers and booleans while identifiers stay as written.
  3. 03Read the type table under the panes. It shows what every column was read as and a real value from your file, so a column that turned into numbers when it should not have is visible before you copy anything.
  4. 04Pick the output shape. An array of objects suits most uses; an object keyed by a column gives you a lookup table; JSON Lines is what bulk-import endpoints want. Pretty print is on because readable output is usually the point.
  5. 05Copy the JSON or download the .json file. If your headers use dots — the shape our JSON to CSV converter produces — switch on nested rebuilding and the objects come back with their original structure.

Four things people do with the output

A test fixture from a spreadsheet

Someone sends a spreadsheet of cases; you need it as a fixture with the codes intact.

CSV
sku,qty
00431,2
JSON, text mode
[{"sku": "00431", "qty": "2"}]

A lookup table keyed by ID

You want O(1) access by identifier rather than a list you have to scan.

Setting
Output shape: Keyed object → id
JSON
{"a1": {"name": "Ada"}, "b2": {"name": "Grace"}}

Rebuilding a config from a flat sheet

The headers are dotted because the file came out of the JSON to CSV converter.

CSV header
db.host,db.port
JSON, nested rebuilding on
[{"db": {"host": "…", "port": "5432"}}]

Feeding a bulk-import endpoint

The API wants newline-delimited records, not one big array.

Setting
Output shape: JSON Lines
Output
{"id":"1"}
{"id":"2"}

Tips & best practices

  • Start on text mode and look at the type table before changing anything. It costs one glance and it is the whole safety story on this page.
  • If one column must stay text and another must be numeric, convert on text mode and coerce the one column in your own code. No converter can read your intent, and a per-file switch is a blunt instrument.
  • A column reported as mixed means different rows held different types. That is usually a data problem worth looking at rather than a setting to change.
  • Getting a stray character on your first column name? That is a byte-order mark from Excel. It is stripped here automatically; in Python use encoding="utf-8-sig".
  • Ragged rows are reported, not padded. A row with the wrong number of fields means the file is malformed — usually an unescaped quote earlier in it.
  • Need the other direction, or want to check this one? The JSON to CSV converter is the inverse and uses the same parser, so a round trip through both is a real test of your file.
  • Once you have the JSON, the JSON formatter will re-indent it, sort the keys or validate it — this page produces the data, that one grooms it.
  • Converting two exports to compare? Use identical settings for both and put the results through the diff checker; differing inference settings will show up as differences that are not in the data.

Gotchas — what this conversion gets wrong

Inference destroys identifiers, quietly and permanently

A ZIP code of 02134, a SKU of 00431, an account number, a Snowflake ID of nineteen digits: each of these looks numeric and none of them is a number. Coerced, they come out as 2134, 431, and an ID that is off by one or two because JSON numbers are doubles and cannot hold an integer past 9007199254740991 exactly. Nothing downstream can detect it, because the output is valid JSON containing plausible numbers. Text mode changes nothing; Safe mode recognises both shapes and leaves them as strings.

A CSV has no schema, so one column can hold three types

Nothing stops row 1 having 42 in a column, row 2 having N/A and row 3 being empty. There is no declaration anywhere in the file saying what that column is meant to be. This tool reports such a column as mixed rather than picking a winner, because the honest answer is that the file does not say — and a converter that decides for you will decide differently on the next export.

A ragged row means the file is broken, not that it needs padding

When a row has fewer or more fields than the header, something upstream went wrong — most often an unescaped quote earlier in the file, which swallows the rest of a line into one field. Padding it silently turns a detectable error into a wrong answer, so rows here are converted as they are and the mismatch is reported with the counts.

Excel may have corrupted the file before you exported it

Open a CSV in Excel and it rewrites what it displays: leading zeros vanish, values that resemble dates become dates, long IDs are rounded to fifteen significant digits. Save from there and the damage is now in the file. If your data went through Excel on the way here, check it against the source before blaming the conversion — no converter can restore a zero that was dropped before it arrived.

Comma is not universal

Where the decimal separator is a comma — most of continental Europe — spreadsheets write and expect semicolons instead. A file from a colleague in Berlin will not split on commas, and pasted into a comma-only converter it becomes one column per row. Detection here scores each candidate by whether it produces a consistent field count on every line, which is what tells a real delimiter from one that merely appears in the data; whatever it picks is named on screen and you can override it.

A CSV upload is usually an export of real people

The files that reach these converters are customer lists, order histories, payroll extracts. That makes it worth knowing where the processing happens. Two of the most familiar names in this space offer save-and-share links; one of them states in its own help that anything stored without signing in is visible to everybody, and a plain search for either turns up other people's uploads sitting at ordinary URLs. Nothing here leaves the tab, which you can verify by turning off your network and converting anyway.

Technical details

Parsing
RFC 4180 character scanner — quoted delimiters, embedded newlines and doubled quotes all handled; never a line split
Delimiter detection
Comma, semicolon, tab and pipe, scored by consistent field count across lines rather than by frequency, and always named on screen
Header handling
Duplicates renamed with a _2 suffix and reported; empty names become column_N; the BOM is stripped
Type inference
Off by default. Safe types protects leading zeros and integers past 2⁵³. Dates are never converted in any mode
Output shapes
Array of objects · object keyed by a column · array of arrays · JSON Lines, pretty or minified
Nested rebuilding
Dotted headers become nested objects — the exact inverse of the JSON to CSV converter's default flattening
Limits
Files larger than 12 MB are declined before the parser starts. Past 2 MB the preview stops early, though what you copy or save is always the complete document
Network
None from tool code. A test sweep calls every function this page uses with fetch and XMLHttpRequest replaced by stubs that throw, so a stray request fails the build instead of shipping. Disconnect from the network and the page still works.

Frequently asked questions

How do I convert CSV to JSON?

Paste the CSV on the left and the JSON appears on the right. The only setting worth thinking about first is Value types, which decides whether your cells stay as text or become numbers and booleans.

Why is everything in my output a string?

Because that is the default, and it is deliberate: text is the only lossless reading of a CSV. Switch Value types to Safe types for numbers and booleans without risking your identifier columns.

My ID column lost its leading zeros. What happened?

The All types mode read it as a number. Use Text only or Safe types — Safe recognises that a value beginning with a zero is not a number and leaves it as written. If the zeros were already gone in the file, Excel removed them before you got here.

What is the difference between Safe types and All types?

Safe types converts numbers and true/false but refuses to touch anything with leading zeros or any integer past 9007199254740991. All types converts those too, plus yes/no and y/n, and the column table marks which columns it changed.

Can I get an object instead of an array?

Yes — set Output shape to Keyed object and choose which column supplies the keys. If those values are not unique you will be told how many rows overwrote an earlier one.

Are dates converted to date objects?

No, in any mode. JSON has no date type, so an ISO string is already the correct representation; producing a Date would only turn back into a string of a different shape when serialised.

My file uses semicolons. Will it work?

Yes. Detection scores each candidate delimiter by whether it gives a consistent field count on every line, so semicolon, tab and pipe files are read correctly — and the delimiter it chose is displayed, with an override if you disagree.

How do I convert CSV to JSON in Python?

csv.DictReader with encoding="utf-8-sig" gives string values and strips the BOM, then json.dump. With pandas use pd.read_csv(path, dtype=str) — without dtype=str it infers types and your ID columns become integers.