CSV to JSON: The Complete Conversion Guide for Developers

posted 5 min read

CSV and JSON are the two most common formats for structured data interchange. Here's how to convert between them correctly, with practical code for every language.

Why the conversion is needed

CSV (Comma-Separated Values) is the universal format for tabular data — every spreadsheet tool and most database exports can produce it. JSON is the universal format for APIs and NoSQL databases. Converting between them is one of the most common data engineering tasks.

For a quick one-off conversion (a CSV export from Google Sheets → JSON for a frontend), a CSV to JSON converter is the fastest approach — paste the CSV and get properly structured JSON immediately.

The structure mapping

A CSV file like this:

``csv

name,age,city

Alice,30,London

Bob,25,New York

Charlie,35,Tokyo

`

Becomes this JSON array:

<code>json <p>[</p> <p>{"name": "Alice", "age": "30", "city": "London"},</p> <p>{"name": "Bob", "age": "25", "city": "New York"},</p> <p>{"name": "Charlie", "age": "35", "city": "Tokyo"}</p> <p>]</p> </code>

The first row becomes the keys; each subsequent row becomes an object in the array.

The type inference problem

CSV stores all values as text. When converting to JSON, you need to decide which columns become numbers, booleans, or nulls.

Without type inference:
<code>json <p>{"name": "Alice", "age": "30", "active": "true"}</p> </code>

With type inference:
<code>json <p>{"name": "Alice", "age": 30, "active": true}</p> </code>

Type inference is almost always what you want. But watch out for edge cases:

  • Leading zeros: 00123123 (integer loses the leading zeros). ZIP codes, account numbers, and phone numbers must stay as strings.
  • Boolean words: yes/no, true/false should be inferred as booleans in most cases
  • Dates: 2026-05-30 — keep as string unless you specifically need Date objects

JavaScript (Node.js)

Using csv-parse:

<code>bash <p>npm install csv-parse</p> </code>

`javascript
import { parse } from 'csv-parse/sync';


import fs from 'fs';

// From file

const content = fs.readFileSync('data.csv', 'utf-8');

// Parse with header row and type casting

const records = parse(content, {

columns: true, // Use first row as keys

skip_empty_lines: true,

cast: true, // Auto-detect types (numbers, booleans)

cast_date: false // Don't auto-convert dates (keeps them as strings)

});

console.log(JSON.stringify(records, null, 2));

`

From a fetch response:

<code>javascript <p>const response = await fetch('/api/data.csv');</p> <p>const csv = await response.text();</p> <p>const records = parse(csv, { columns: true, cast: true });</p> </code>

Async (streaming, for large files):

`javascript
import { createReadStream } from 'fs';


import { parse } from 'csv-parse';

const records = [];

createReadStream('large.csv')

.pipe(parse({ columns: true, cast: true }))

.on('data', record => records.push(record))

.on('end', () => console.log(JSON.stringify(records, null, 2)));

`

Python

Built-in csv module:

`python
import csv, json

with open('data.csv') as f:

reader = csv.DictReader(f)

records = list(reader)

All values are strings — cast manually if needed

def cast_row(row):

result = {}

for key, value in row.items():

try:

result[key] = int(value)

except ValueError:

try:

result[key] = float(value)

except ValueError:

if value.lower() == 'true':

result[key] = True

elif value.lower() == 'false':

result[key] = False

else:

result[key] = value

return result

records = [cast_row(row) for row in records]

print(json.dumps(records, indent=2))

`

Pandas (recommended for data work):

`python
import pandas as pd


import json

Read CSV with type inference

df = pd.read_csv('data.csv')

Convert to JSON

json_str = df.to_json(orient='records', indent=2)

Or get a list of dicts

records = df.to_dict(orient='records')

print(json.dumps(records, indent=2))

Handle specific column types

df = pd.read_csv('data.csv', dtype={

'zip_code': str, # Keep as string (leading zeros)

'phone': str, # Keep as string

'age': int # Force integer

})

`

Handling quoted fields with commas

CSV fields containing commas must be wrapped in double quotes per RFC 4180:

<code>csv <p>name,address,city</p> <p>Alice,"123 Main St, Apt 4",London</p> </code>

All standard CSV parsers handle this automatically. Don't parse CSV with String.split(',') — it breaks on quoted fields.

Handling special delimiters

Not all CSV files use commas:

<code>csv <p>name;age;city ← semicolons (common in European countries)</p> <p>name|age|city ← pipes</p> <p>name\tage\tcity ← tabs (TSV format)</p> </code>

csv-parse:
<code>javascript <p>parse(content, { delimiter: ';' }) // semicolons</p> <p>parse(content, { delimiter: '\t' }) // tabs</p> </code>

Pandas:
<code>python <p>pd.read_csv('data.csv', sep=';')</p> <p>pd.read_csv('data.tsv', sep='\t')</p> </code>

Handling multiple headers (nested JSON)

If your CSV has address.street and address.city as column names, you may want nested JSON output:

<code>csv <p>name,address.street,address.city</p> <p>Alice,123 Main St,London</p> </code>

<code>json <p>[{"name": "Alice", "address": {"street": "123 Main St", "city": "London"}}]</p> </code>

Python:
`python
def unflatten(flat_dict, sep='.'):


result = {}


for key, value in flat_dict.items():


parts = key.split(sep)


d = result


for part in parts[:-1]:


d = d.setdefault(part, {})


d[parts[-1]] = value


return result

records = [unflatten(row) for row in csv.DictReader(open('data.csv'))]

`

Command line

`bash
Python (no extra deps)
python3 -c "


import csv, json, sys


reader = csv.DictReader(sys.stdin)


print(json.dumps(list(reader), indent=2))


" < data.csv

With jq (for further filtering)

python3 -c "import csv, json, sys; print(json.dumps(list(csv.DictReader(sys.stdin))))" < data.csv | jq '.[] | select(.city == "London")'

csvtojson (Node.js CLI)

npm install -g csvtojson

csvtojson data.csv > data.json

`


The main decisions when converting CSV to JSON are: use the first row as keys (almost always yes), handle type inference carefully for columns with leading zeros, and pick the right parser (not String.split(',')`). For one-off conversions, a browser tool is fastest; for automated pipelines, Pandas (Python) or csv-parse (Node.js) are the most capable options.

Originally published at https://snappytools.app/csv-to-json-converter/

More Posts

Sovereign Intelligence: The Complete 25,000 Word Blueprint (Download)

Pocket Portfolio - Apr 1

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelskiverified - Mar 19

TypeScript Complexity Has Finally Reached the Point of Total Absurdity

Karol Modelskiverified - Apr 23

Just completed another large-scale WordPress migration — and the client left this

saqib_devmorph - Apr 7

5 Web Dev Pitfalls That Are Silently Killing Your Projects (With Real Fixes)

Dharanidharan - Mar 3
chevron_left

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!