Nested JSON Flattening Techniques — Turn Deep Objects into Flat Key-Value Pairs

API responses are often deeply nested — objects inside objects, arrays inside objects, three or four levels deep. That is great for expressing relationships, but it is painful when you need to export the data to CSV, load it into a spreadsheet, or feed it into an analytics tool that expects flat rows and columns. This guide covers practical techniques for flattening nested JSON, with a reusable JavaScript function.

What Flattening Looks Like

A nested object becomes a single-level object where each key is the "path" to the original value, joined by dots:

// Before (nested)
{
  "id": 501,
  "customer": {
    "name": "Priya Sharma",
    "address": {
      "city": "Bengaluru",
      "pincode": "560001"
    }
  },
  "active": true
}

// After (flattened)
{
  "id": 501,
  "customer.name": "Priya Sharma",
  "customer.address.city": "Bengaluru",
  "customer.address.pincode": "560001",
  "active": true
}

A Recursive Flatten Function in JavaScript

This function walks the object tree recursively and builds dotted keys for nested objects. Arrays are kept as indexed keys so no data is lost:

function flattenJson(obj, parentKey = '', result = {}) {
  for (const key in obj) {
    if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;

    const value = obj[key];
    const newKey = parentKey ? `${parentKey}.${key}` : key;

    if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
      // Nested object — recurse
      flattenJson(value, newKey, result);
    } else if (Array.isArray(value)) {
      // Array — flatten each element with an index
      value.forEach((item, index) => {
        const arrayKey = `${newKey}[${index}]`;
        if (item !== null && typeof item === 'object') {
          flattenJson(item, arrayKey, result);
        } else {
          result[arrayKey] = item;
        }
      });
    } else {
      result[newKey] = value;
    }
  }
  return result;
}

const nested = {
  id: 501,
  customer: {
    name: "Priya Sharma",
    address: { city: "Bengaluru", pincode: "560001" }
  },
  tags: ["vip", "returning"]
};

console.log(flattenJson(nested));
// {
//   id: 501,
//   'customer.name': 'Priya Sharma',
//   'customer.address.city': 'Bengaluru',
//   'customer.address.pincode': '560001',
//   'tags[0]': 'vip',
//   'tags[1]': 'returning'
// }

Handling Arrays of Objects (Multiple Rows)

When flattening a JSON array of records — for CSV export, for example — flatten each record independently and collect the results into an array of flat rows:

const orders = [
  { id: 1, customer: { name: "Priya", city: "Bengaluru" } },
  { id: 2, customer: { name: "Rahul", city: "Pune" } }
];

const flatRows = orders.map(order => flattenJson(order));

console.log(flatRows);
// [
//   { id: 1, 'customer.name': 'Priya', 'customer.city': 'Bengaluru' },
//   { id: 2, 'customer.name': 'Rahul', 'customer.city': 'Pune' }
// ]

When to Use a Library Instead

The recursive function above works well for most cases, but for production pipelines consider a battle-tested library:

  • flat (npm) — a small, widely used package with flatten() and unflatten() for round-tripping data.
  • lodash — no built-in flatten-object helper, but _.get/_.set pair well with a custom flattener.
  • json2csv — handles flattening and CSV conversion together in one step for Node.js pipelines.
  • pandas.json_normalize (Python) — the standard way to flatten nested JSON into a DataFrame for CSV or Excel export.

Common Pitfalls

  • Key collisions — if two nested paths produce the same flat key, one will silently overwrite the other. Use a unique delimiter and check for collisions on large datasets.
  • Very deep nesting — extremely deep structures create long, unreadable column names. Consider limiting flatten depth for readability.
  • Mixed array content — arrays containing both objects and primitives need special-case handling, as shown in the function above.
  • Null vs missing keys — flattening does not fill in missing keys across records; when exporting to CSV, normalize the column set across all rows first.

Frequently Asked Questions

What does it mean to flatten a JSON object?

Flattening a JSON object means converting a nested structure with objects inside objects into a single-level object where each key represents the full path to a value, such as "address.city" instead of a nested address object containing a city field.

Why flatten JSON before exporting to CSV?

CSV is a flat, tabular format with no concept of nested structures. Flattening JSON first converts each nested field into its own column, such as address_city and address_pincode, so the data maps cleanly onto CSV rows and columns.

Is there a free tool to format and inspect nested JSON?

Yes. Dev Brains AI JSON Formatter pretty-prints deeply nested JSON so you can inspect its structure before writing a flattening script.

Try the Free JSON Formatter

Pretty-print and inspect nested JSON before you write a flattening or export script. No signup, no cost.

Related articles