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”.
| Column | Read as | Sample from your file |
|---|
One row, every setting
| Setting | Reading 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 off | The 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 CSV | What a careless conversion gives | How to keep it |
|---|---|---|
007 — a ZIP, SKU or account code | 7, and the zeros are unrecoverable | Text only or Safe types. Safe recognises leading zeros and leaves them alone |
9007199254740993 — a database or Snowflake ID | 9007199254740992, silently off by one | Text only or Safe types. Past 2⁵³ a JSON number cannot hold the value exactly |
+44 20 7946 0958 — a phone number | Usually survives, but 0207946095 would not | Text only or Safe types; never All types for contact data |
01/02/2026 — an ambiguous date | A string either way here, but Excel may already have rewritten it | Nothing is date-converted in any mode — JSON has no date type |
TRUE, yes, N | true / false, including where the column meant a letter grade | Text only, or check the type table before you commit |
| An empty cell | "" here by default; some converters give null | The 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
- 01Paste or upload the file. The delimiter is detected and named on screen rather than silently chosen — if the detection is wrong, override it.
- 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.
- 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.
- 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.
- 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.
sku,qty 00431,2
[{"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.
Output shape: Keyed object → id
{"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.
db.host,db.port
[{"db": {"host": "…", "port": "5432"}}]Feeding a bulk-import endpoint
The API wants newline-delimited records, not one big array.
Output shape: JSON Lines
{"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
fetchandXMLHttpRequestreplaced 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.