Back to Blog

How to Convert CSV to JSON (and Back)

Published: March 31, 2026

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.city become separate columns
  • Stringify nested objects: The address column 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.