Skip to content
Back to Learn
·5 min read

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 StructureCSV ChallengeCommon Solution
Nested objects ({"address":{"city":"NYC"}})No nested columnsFlatten to dot notation: address.city
Arrays ({"tags":["a","b","c"]})One value per cellJoin with delimiter or create multiple columns
Mixed types ([1, "two", true])Uniform column typesConvert all to strings
Dynamic keys ({"user_1": {...}})Fixed columnsUse all unique keys across all objects
Null values ({"field": null})Empty cellsLeave 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

DatasetJSON (minified)CSVWinner
100 rows, 10 columns4.2 KB3.1 KBCSV
10K rows, 50 columns2.1 MB1.3 MBCSV
Deeply nested (10 levels)1.5 MB0.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.