DataShift

Convert JSON to CSV Online

Paste any JSON — flat, nested, or full of arrays — and get a clean CSV in seconds. No uploads, no account.

JSON → CSV

Free JSON to CSV converter that handles nested objects and arrays. Paste a Stripe webhook, GitHub API response, or any real-world JSON and get a flat, download-ready CSV. Works entirely in your browser.

100% local — no uploads
Input · JSON

Output will appear here

How to use the JSON → CSV

  1. Paste or upload your JSON data

    Paste text directly into the input box, drag and drop a file onto it, or click "Upload file" to browse. Conversion starts instantly on paste — no button click required.

  2. Configure options (optional)

    Open the Options panel to customise delimiter, headers, nested-object flattening, and more. Use the Field Selector to pick exactly which columns appear in the output.

  3. Copy or download your CSV

    Click Copy to grab the result, or Download to save the file. Everything runs locally in your browser — no data ever leaves your device.

Example

Input (JSON)

[
  { "id": 1, "name": "Alice", "city": "NYC" },
  { "id": 2, "name": "Bob",   "city": "LA"  }
]

Output (CSV)

id,name,city
1,Alice,NYC
2,Bob,LA

Frequently Asked Questions

Is my data safe?
Yes. Every conversion runs entirely inside your browser. No data is ever transmitted to a server. The tool works offline once loaded.
What is the maximum file size?
There is no hard limit. Files under 1 MB convert instantly. Files 1–10 MB show a progress indicator. Files over 10 MB prompt a warning and run in a background thread to keep the browser responsive.
Why does my JSON fail to parse?
Common causes are trailing commas, single-quoted strings, unquoted keys, or missing closing brackets. The converter auto-repairs many of these and tells you exactly what it changed.
Can I convert multiple files at once?
The tool handles one file at a time. For bulk conversion, consider the csvjson CLI or API.
How does the converter handle nested JSON?
Nested objects are flattened with dot-notation keys (e.g. address.city). Arrays of objects expand into multiple rows by default. Both behaviours can be toggled in the Options panel.

How it works

Step 1

Nested objects become dot-notation columns

When your JSON contains nested objects like `customer: { id: "cus_123", email: "..." }`, each nested field becomes its own column using dot notation: `customer.id` and `customer.email`. Most converters give up here or produce `[object Object]` — this one maps every level of nesting into flat columns.

Step 2

Arrays of objects expand into rows

If a field contains an array of objects — like a Stripe charge's `line_items` — each element becomes its own row, with the parent fields repeated. So one payment with three line items produces three CSV rows, each carrying the payment ID, amount, and the specific line item data. You get a properly relational table instead of "[{...},{...}]" stuffed into a single cell.

Step 3

Primitive arrays join into one cell

When a field is an array of strings or numbers — like `tags: ["billing", "auto"]` — the values are joined with a separator ("; " by default, configurable). This keeps the row count predictable when you don't need to expand every array.

Example

Stripe Payment Intents API response

Input
[
  {
    "id": "pi_3MtwBwLkdIwHu7ix28a3tqPD",
    "amount": 2000,
    "currency": "usd",
    "status": "succeeded",
    "customer": {
      "id": "cus_NffrFeUfNV2Hib",
      "email": "jenny.rosen@example.com",
      "name": "Jenny Rosen"
    },
    "payment_method_details": {
      "type": "card",
      "card": {
        "brand": "visa",
        "last4": "4242",
        "exp_month": 8,
        "exp_year": 2026
      }
    },
    "metadata": {
      "order_id": "6735"
    }
  }
]
Output
id,amount,currency,status,customer.id,customer.email,customer.name,payment_method_details.type,payment_method_details.card.brand,payment_method_details.card.last4,payment_method_details.card.exp_month,payment_method_details.card.exp_year,metadata.order_id
pi_3MtwBwLkdIwHu7ix28a3tqPD,2000,usd,succeeded,cus_NffrFeUfNV2Hib,jenny.rosen@example.com,Jenny Rosen,card,visa,4242,8,2026,6735

The three levels of nesting (customer, payment_method_details, card) are each flattened into their own columns using dot-separated paths. The result is a single, queryable row per payment — ready for Excel, Google Sheets, or a SQL import.

Edge cases, handled

Mixed-depth objects

If some records have a field and others don't, missing fields are written as empty cells. The column still appears, preserving a uniform schema across all rows.

Deeply nested arrays within arrays

The flattener walks the full tree. A charge inside a payment_intent inside an invoice will still produce a row — the path just gets longer: invoice.payment_intent.charge.amount.

Keys with dots in their names

If your JSON already has a key like `"user.id"` (with a literal dot), it's escaped as `user\.id` in the column header so it doesn't collide with a nested path of the same name.

Frequently asked questions

What happens when different records have different fields?

The column set is the union of all fields across every record. If record A has a `shipping` object and record B doesn't, every row still has the `shipping.*` columns — they're just empty for record B. This means the schema is consistent and you won't have ragged rows.

My JSON has arrays of objects inside it. How does expansion work?

When a field contains an array of objects (like Stripe's `line_items` or GitHub's `labels`), each element in the array becomes its own CSV row. The parent fields are repeated on every row. So one invoice with four line items produces four CSV rows, each with the invoice ID and the specific line item. If you'd rather keep them joined, you can switch to 'inline' mode, which serializes the whole array as JSON in one cell.

Why do other JSON-to-CSV converters produce '[object Object]' or break entirely?

Most online converters call JavaScript's `.toString()` on any value that isn't a string or number, which gives you the useless `[object Object]`. The few that try to flatten usually only go one level deep and give up on arrays. csvjson's flattener recurses the full tree and has explicit strategies for each data shape — objects, arrays of objects, arrays of primitives — so it doesn't fall back to a string representation.

Can I choose which fields to include in the output?

Yes. After conversion, the Field Selector panel shows a checkbox tree of every column. You can deselect entire groups (like `metadata.*`), pick only numeric fields, or filter by name. The CSV regenerates instantly with only the selected columns.

Is there a file size limit?

No. Everything runs in your browser using JavaScript — there's no upload to a server, so there's no server-side limit. Large files (10 MB+) will show a progress indicator. The practical limit is your browser's available RAM, which is typically several gigabytes.