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: 00123
→ 123 (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/