Flatten deeply nested JSON objects into CSV-ready flat objects — and unflatten them back. Zero dependencies.
🔧 Don't want to write code? Use the free online tool → jsoncsv.tools
Converting nested JSON to CSV is surprisingly hard. Most tools either:
- Ignore nested objects entirely
- Stringify them as
[object Object] - Crash on arrays or circular references
json-csv-flatten handles all of this correctly:
| Feature | json-csv-flatten | JSON.stringify |
Other libs |
|---|---|---|---|
| Nested objects → dot notation | ✅ | ❌ | |
| Arrays → indexed keys | ✅ | ❌ | |
| Depth limit (circular protection) | ✅ | ❌ | ❌ |
| Round-trip (flatten ↔ unflatten) | ✅ | ❌ | |
| Standardize keys across rows | ✅ | ❌ | ❌ |
| Zero dependencies | ✅ | ✅ | ❌ |
| TypeScript types included | ✅ | — |
npm install json-csv-flattenconst { flatten, unflatten } = require('json-csv-flatten');
// Flatten nested JSON
const flat = flatten({
user: {
name: 'John',
address: { city: 'Kyiv', zip: 01001 }
},
tags: ['developer', 'musician']
});
console.log(flat);
// {
// 'user.name': 'John',
// 'user.address.city': 'Kyiv',
// 'user.address.zip': 513,
// 'tags.0': 'developer',
// 'tags.1': 'musician'
// }
// Unflatten back to nested
const nested = unflatten(flat);
console.log(nested);
// { user: { name: 'John', address: { city: 'Kyiv', zip: 513 } }, tags: ['developer', 'musician'] }Flattens a nested object into a single-level object with dot-notation keys.
flatten({ a: { b: { c: 1 } } })
// → { 'a.b.c': 1 }Options:
| Option | Type | Default | Description |
|---|---|---|---|
separator |
string |
'.' |
Separator for nested keys |
maxDepth |
number |
10 |
Max recursion depth (prevents infinite loops) |
Unflattens a flat object back into a nested object. Automatically reconstructs arrays from numeric indices.
unflatten({ 'user.name': 'John', 'user.scores.0': '90', 'user.scores.1': '85' })
// → { user: { name: 'John', scores: [90, 85] } }Smart type detection: String values like "true", "false", "123" are automatically converted to their native types. Leading zeros (e.g., "01234") are preserved as strings.
Options:
| Option | Type | Default | Description |
|---|---|---|---|
separator |
string |
'.' |
Separator used in the flat keys |
Flattens an array of nested objects and standardizes their keys (fills missing keys with null). This is what you want when preparing data for CSV export.
const { flattenArray } = require('json-csv-flatten');
const rows = flattenArray([
{ user: { name: 'John' }, age: 30 },
{ user: { name: 'Jane', city: 'London' }, age: 25 }
]);
console.log(rows);
// [
// { 'user.name': 'John', 'user.city': null, age: 30 },
// { 'user.name': 'Jane', 'user.city': 'London', age: 25 }
// ]
// Now every row has the same columns — ready for CSV!Takes an array of flat objects and ensures every object has every key (missing ones filled with null).
standardizeKeys([{ a: 1, b: 2 }, { a: 3, c: 4 }])
// → [{ a: 1, b: 2, c: null }, { a: 3, b: null, c: 4 }]// Use underscore instead of dot
flatten({ user: { name: 'John' } }, { separator: '_' })
// → { 'user_name': 'John' }
unflatten({ 'user_name': 'John' }, { separator: '_' })
// → { user: { name: 'John' } }Deeply nested or accidentally circular structures won't crash your app:
flatten(deeplyNestedObj, { maxDepth: 5 })
// Keys deeper than 5 levels → '[MAX_DEPTH exceeded]'json-csv-flatten gives you flat objects — pair it with any CSV library:
const { flattenArray } = require('json-csv-flatten');
const { unparse } = require('papaparse');
const data = [
{ user: { name: 'John', address: { city: 'Kyiv' } }, active: true },
{ user: { name: 'Jane', address: { city: 'London' } }, active: false }
];
const csv = unparse(flattenArray(data));
console.log(csv);
// user.name,user.address.city,active
// John,Kyiv,true
// Jane,London,falseDon't need a library? Just drag & drop your JSON file at jsoncsv.tools — free, private (files never leave your browser), handles nested objects perfectly.