How to Convert CSV to JSON (and Back)
How to Convert CSV to JSON (and Back)
Meta description: Step-by-step guide to converting CSV files to JSON and JSON to CSV. Includes online tools, Python scripts, and JavaScript methods.
CSV and JSON are both text-based data formats, but they serve different purposes. CSV is the go-to for spreadsheets and tabular data. JSON is the standard for APIs and web applications. Sooner or later, you'll need to convert between the two.
Here's how to do it properly.
CSV to JSON: The Basic Idea
A CSV file like this:
csv
name,age,city
Alice,30,Paris
Bob,25,London
Charlie,35,Berlin
Becomes this JSON:
json
[
{"name": "Alice", "age": "30", "city": "Paris"},
{"name": "Bob", "age": "25", "city": "London"},
{"name": "Charlie", "age": "35", "city": "Berlin"}
]
Each row becomes an object. Each column header becomes a key. Straightforward.
Method 1: Python (Most Flexible)
Python makes this trivially easy with built-in libraries.
CSV to JSON
python
import csv
import json
with open('data.csv', 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
rows = list(reader)
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(rows, f, indent=2, ensure_ascii=False)
print(f"Converted {len(rows)} rows")
JSON to CSV
python
import csv
import json
with open('data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
if data:
with open('data.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
print(f"Converted {len(data)} records")
With Pandas (For Larger Files)
python
import pandas as pd
CSV to JSON
df = pd.read_csv('data.csv')
df.tojson('data.json', orient='records', indent=2, forceascii=False)
JSON to CSV
df = pd.read_json('data.json')
df.to_csv('data.csv', index=False)
Method 2: JavaScript / Node.js
CSV to JSON (Node.js)
javascript
import { readFileSync, writeFileSync } from 'fs';
const csv = readFileSync('data.csv', 'utf-8');
const lines = csv.trim().split('\n');
const headers = lines[0].split(',');
const json = lines.slice(1).map(line => {
const values = line.split(',');
return Object.fromEntries(headers.map((h, i) => [h.trim(), values[i]?.trim()]));
});
writeFileSync('data.json', JSON.stringify(json, null, 2));
Warning: This naive parser doesn't handle quoted fields, commas inside values, or newlines within cells. For production use, grab a proper CSV parser like PapaParse.
JSON to CSV (Node.js)
javascript
import { readFileSync, writeFileSync } from 'fs';
const data = JSON.parse(readFileSync('data.json', 'utf-8'));
const headers = Object.keys(data[0]);
const csv = [
headers.join(','),
...data.map(row => headers.map(h => {
const val = String(row[h] ?? '');
return val.includes(',') ? "${val}" : val;
}).join(','))
].join('\n');
writeFileSync('data.csv', csv);
Method 3: Command Line
Using jq (JSON processor)
bash
CSV to JSON (simple, no quoted fields)
python3 -c "
import csv, json, sys
reader = csv.DictReader(open('data.csv'))
json.dump(list(reader), sys.stdout, indent=2)
" > data.json
JSON to CSV using jq + Miller
mlr --json2csv cat data.json > data.csv
Using Miller (mlr)
Miller is a fantastic CLI tool for data format conversion:
bash
CSV to JSON
mlr --csv2json cat data.csv > data.json
JSON to CSV
mlr --json2csv cat data.json > data.csv
CSV to JSON with pretty printing
mlr --csv2json --jflatsep '.' cat data.csv > data.json
Method 4: Online (No Code)
If you just need to verify your CSV structure before converting, load it into CSV Viewer Online to check that columns, delimiters, and encoding are correct. Clean data converts cleanly.
For the actual conversion, several free online tools handle CSV-to-JSON and back without needing to write code.
The Tricky Parts
Nested JSON Won't Flatten Nicely
JSON like this doesn't map cleanly to CSV:
json
{
"name": "Alice",
"address": {
"street": "123 Main St",
"city": "Paris"
},
"orders": [101, 102, 103]
}
You have two choices:
- Flatten it:
address.street,address.citybecome separate columns
- Stringify nested objects: The
addresscolumn contains{"street":"123 Main St","city":"Paris"}as a string
Neither is perfect. Flattening creates many columns. Stringifying makes the CSV harder to use in spreadsheets.
python
import pandas as pd
Flatten nested JSON
df = pd.jsonnormalize(data, sep='')
df.to_csv('flattened.csv', index=False)
Data Types Are Lost in CSV
JSON has numbers, strings, booleans, and null. CSV has... strings. Everything becomes text.
json
{"active": true, "count": 42, "name": "Alice"}
In CSV, true becomes the text "true", 42 becomes "42". When converting back, you'll need to explicitly cast types:
python
import pandas as pd
df = pd.read_csv('data.csv')
df['count'] = pd.to_numeric(df['count'])
df['active'] = df['active'].map({'true': True, 'false': False})
Encoding Matters
Always use UTF-8 for both formats. If your CSV has accented characters (common in French, German, Spanish data), make sure you specify encoding explicitly:
python
Reading
df = pd.read_csv('data.csv', encoding='utf-8')
If UTF-8 doesn't work, try:
df = pd.read_csv('data.csv', encoding='latin-1')
Large Files Need Streaming
For files with millions of rows, don't load everything into memory at once:
python
import csv
import json
with open('huge.csv', 'r') as infile, open('huge.json', 'w') as outfile:
reader = csv.DictReader(infile)
outfile.write('[\n')
for i, row in enumerate(reader):
if i > 0:
outfile.write(',\n')
json.dump(row, outfile)
outfile.write('\n]')
Quick Reference
| From | To | Best Tool |
|------|-----|-----------|
| Small CSV | JSON | Online converter or Python |
| Large CSV (100K+ rows) | JSON | Python with streaming |
| Simple JSON array | CSV | Python or mlr |
| Nested JSON | CSV | pd.json_normalize() |
| Quick format check | β | CSV Viewer Online |
When Not to Convert
Before you convert, ask yourself: do you actually need to?
- If you're importing into a database, most databases accept both formats directly.
- If you're building an API, keep the data in JSON β that's what APIs speak.
- If you're sending data to a non-technical person, keep it as CSV β they can open it in Excel.
- If you're archiving data, CSV is more durable (no syntax issues, universally readable).
Converting between formats is easy. The hard part is knowing when it's actually necessary.