Nested JSON is great for representing complex data relationships, but it's a nightmare when you need to put the data into a spreadsheet, database table, or CSV file. Flattening converts nested structures into flat key-value pairs — here's how to do it in every major way.
What is JSON flattening?
Flattening turns deeply nested JSON into a single-level object where nested keys are combined with a separator:
// Nested (before)
{
"user": {
"name": "Alice",
"address": {
"city": "Paris",
"zip": "75001"
}
}
}
// Flattened (after)
{
"user.name": "Alice",
"user.address.city": "Paris",
"user.address.zip": "75001"
}
Flatten JSON in JavaScript
function flattenJSON(obj, prefix = '', separator = '.') {
return Object.keys(obj).reduce((acc, key) => {
const fullKey = prefix ? prefix + separator + key : key;
if (
typeof obj[key] === 'object' &&
obj[key] !== null &&
!Array.isArray(obj[key])
) {
Object.assign(acc, flattenJSON(obj[key], fullKey, separator));
} else {
acc[fullKey] = obj[key];
}
return acc;
}, {});
}
// Usage
const nested = {
user: {
name: "Alice",
address: { city: "Paris", zip: "75001" }
},
score: 95
};
console.log(flattenJSON(nested));
// {
// "user.name": "Alice",
// "user.address.city": "Paris",
// "user.address.zip": "75001",
// "score": 95
// }
Flatten JSON in Python
def flatten_json(obj, prefix='', separator='.'):
items = {}
for key, value in obj.items():
full_key = f"{prefix}{separator}{key}" if prefix else key
if isinstance(value, dict):
items.update(flatten_json(value, full_key, separator))
elif isinstance(value, list):
for i, item in enumerate(value):
if isinstance(item, dict):
items.update(flatten_json(item, f"{full_key}[{i}]", separator))
else:
items[f"{full_key}[{i}]"] = item
else:
items[full_key] = value
return items
nested = {
"user": {
"name": "Alice",
"address": {"city": "Paris", "zip": "75001"}
},
"score": 95
}
print(flatten_json(nested))
# {'user.name': 'Alice', 'user.address.city': 'Paris', ...}
Flatten with pandas (for CSV export)
import pandas as pd
data = [
{"name": "Alice", "address": {"city": "Paris", "zip": "75001"}},
{"name": "Bob", "address": {"city": "London", "zip": "EC1A"}}
]
# json_normalize automatically flattens nested objects
df = pd.json_normalize(data)
print(df.columns.tolist())
# ['name', 'address.city', 'address.zip']
df.to_csv('output.csv', index=False)
Handling arrays in nested JSON
Arrays need special handling — you can either stringify them or explode them into multiple rows:
# Stringify arrays (keep as one cell)
import json
def flatten_stringify_arrays(obj, prefix='', sep='.'):
items = {}
for k, v in obj.items():
key = f"{prefix}{sep}{k}" if prefix else k
if isinstance(v, dict):
items.update(flatten_stringify_arrays(v, key, sep))
elif isinstance(v, list):
items[key] = json.dumps(v) # stringify the array
else:
items[key] = v
return items
Try it free — JSON to CSV Converter
Convert JSON to CSV directly — nested objects are auto-stringified so nothing is lost.