JSON to CSV Guide: Converting Structured Data to Spreadsheets
Converting JSON to CSV is one of the most common data transformation tasks. JSON's nested, hierarchical structure must be flattened into CSV's rigid tabular format. This guide covers every aspect of JSON-to-CSV conversion including flattening strategies, array handling, nested objects, encoding issues, and best practices for large datasets. Use our JSON to CSV Converter for instant conversion and CSV to JSON Converter for the reverse operation.
Why Convert JSON to CSV?
- Spreadsheet analysis — Excel, Google Sheets, and LibreOffice open CSV natively
- Data science — Pandas, R, and MATLAB prefer tabular data
- Database import — SQL databases import CSV directly via COPY/LOAD commands
- Reporting — Business users consume data as spreadsheets
- Archival — CSV is one of the most durable data formats
The Fundamental Challenge: Hierarchical vs Tabular
JSON supports arbitrary nesting and mixed types within arrays. CSV is strictly tabular with one header row and uniform columns per row. Every JSON-to-CSV converter must answer the same questions:
| JSON Structure | CSV Challenge | Common Solution |
|---|---|---|
Nested objects ({"address":{"city":"NYC"}}) | No nested columns | Flatten to dot notation: address.city |
Arrays ({"tags":["a","b","c"]}) | One value per cell | Join with delimiter or create multiple columns |
Mixed types ([1, "two", true]) | Uniform column types | Convert all to strings |
Dynamic keys ({"user_1": {...}}) | Fixed columns | Use all unique keys across all objects |
Null values ({"field": null}) | Empty cells | Leave empty or use NULL text |
Conversion Example
// Input JSON (array of objects)
[
{
"name": "Alice",
"age": 30,
"address": { "city": "New York", "zip": "10001" },
"tags": ["developer", "javascript"]
},
{
"name": "Bob",
"age": 25,
"address": { "city": "San Francisco", "zip": "94105" },
"tags": ["designer"]
}
]
// Output CSV
name,age,address.city,address.zip,tags
Alice,30,New York,10001,"developer; javascript"
Bob,25,San Francisco,94105,designer
JavaScript Implementation
function jsonToCsv(jsonArray, options = {}) {
const { flatten = true, separator = ',', arrayDelimiter = ';' } = options;
// Step 1: Flatten each object
const flattened = jsonArray.map(obj => flattenObject(obj));
// Step 2: Collect all unique keys
const keys = [...new Set(flattened.flatMap(Object.keys))];
// Step 3: Build CSV rows
const header = keys.join(separator);
const rows = flattened.map(obj => {
return keys.map(key => {
let val = obj[key];
if (val === null || val === undefined) return '';
if (Array.isArray(val)) val = val.join(arrayDelimiter);
val = String(val);
// Escape quotes and wrap in quotes if needed
if (val.includes(separator) || val.includes('"') || val.includes('
')) {
val = '"' + val.replace(/"/g, '""') + '"';
}
return val;
}).join(separator);
});
return [header, ...rows].join('
');
}
function flattenObject(obj, prefix = '') {
return Object.keys(obj).reduce((acc, key) => {
const newKey = prefix ? prefix + '.' + key : key;
if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
Object.assign(acc, flattenObject(obj[key], newKey));
} else {
acc[newKey] = obj[key];
}
return acc;
}, {});
}
Handling Complex Scenarios
Array of arrays (not objects)
// Input
[["Name", "Age"], ["Alice", 30], ["Bob", 25]]
// Output (first row = header)
Name,Age
Alice,30
Bob,25
Single object (not array)
// Input: {"name":"Alice","age":30}
// Output (single row with header)
name,age
Alice,30
Deeply nested + arrays
// Input
{
"orders": [
{
"id": 1,
"items": [{"product": "A", "qty": 2}, {"product": "B", "qty": 1}],
"total": 100
}
]
}
// Output (order items exploded into rows)
order.id,order.items.product,order.items.qty,order.total
1,A,2,100
1,B,1,100
Common Pitfalls
- Commas in data — Always quote fields containing commas. Use our JSON to CSV tool which handles this automatically
- Newlines in data — Must be quoted or escaped. This is required by RFC 4180
- Encoding — Excel may not display UTF-8 correctly. Add a UTF-8 BOM for compatibility
- Large files — CSV has no streaming parser. For files over 100MB, consider NDJSON instead
- Type preservation — CSV is string-only. Numbers and booleans become text
- Empty vs null — CSV cannot distinguish empty string from null
Encoding and Excel Compatibility
For Excel to correctly display special characters:
// Add UTF-8 BOM at the start
const BOM = '';
const csvWithBom = BOM + csvContent;
// Or use our tool at /csv-to-json for the reverse conversion
Performance: JSON vs CSV Size
| Dataset | JSON (minified) | CSV | Winner |
|---|---|---|---|
| 100 rows, 10 columns | 4.2 KB | 3.1 KB | CSV |
| 10K rows, 50 columns | 2.1 MB | 1.3 MB | CSV |
| Deeply nested (10 levels) | 1.5 MB | 0.8 MB (flattened) | CSV |
Next Steps
Convert your JSON to CSV with JSON to CSV Converter. Convert CSV back to JSON with CSV to JSON. Validate your JSON before conversion with JSON Validator. Format your JSON first with JSON Formatter to understand its structure.