DataShift

Convert CSV to JSON Online

Turn any spreadsheet export into clean, structured JSON — with dot-notation headers rebuilt into nested objects.

CSV → JSON

Free CSV to JSON converter. Paste a CSV and get a JSON array back. Handles dot-notation column headers like address.city to rebuild nested objects. Perfect for feeding spreadsheet data back into an API.

100% local — no uploads
Input · CSV

Output will appear here

How to use the CSV → JSON

  1. Paste or upload your CSV 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 JSON

    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 (CSV)

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

Output (JSON)

[
  { "id": "1", "name": "Alice", "city": "NYC" },
  { "id": "2", "name": "Bob",   "city": "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 CSV 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.
Will numbers stay as numbers in the JSON output?
Values that look like numbers or booleans are preserved as strings by default to match CSV semantics exactly. Type coercion may be added as an option in a future release.

How it works

Step 1

Column headers become JSON keys

The first row of your CSV becomes the keys of each JSON object. A column named `email` becomes `"email"` in every record. Simple and expected.

Step 2

Dot-notation headers rebuild nested objects

This is what makes this converter different from every basic one. If your CRM export has columns named `address.city`, `address.state`, and `address.zip`, they get reassembled into a proper nested `address` object — not kept as flat keys with dots in their names. A HubSpot, Salesforce, or Airtable export with structured headers comes back out as API-ready JSON, not a flat bag of dotted strings.

Step 3

Types are inferred, not everything becomes a string

Numbers stay numbers. Booleans (`true`/`false`) stay booleans. Empty cells become `null` rather than empty strings. This saves you from writing `parseInt(row.amount)` in every downstream script that consumes the output.

Example

HubSpot CRM export with structured column headers

Input
contact_id,first_name,last_name,email,address.street,address.city,address.state,address.zip,company.name,company.industry
1001,Sarah,Connor,sarah@example.com,742 Evergreen Terrace,Springfield,IL,62701,Cyberdyne Systems,Technology
1002,John,Doe,john@example.com,221B Baker Street,London,UK,NW1 6XE,Acme Corp,Manufacturing
Output
[
  {
    "contact_id": 1001,
    "first_name": "Sarah",
    "last_name": "Connor",
    "email": "sarah@example.com",
    "address": {
      "street": "742 Evergreen Terrace",
      "city": "Springfield",
      "state": "IL",
      "zip": "62701"
    },
    "company": {
      "name": "Cyberdyne Systems",
      "industry": "Technology"
    }
  }
]

The address.* and company.* columns are reassembled into properly nested objects — exactly the shape an API or database ORM would expect. You can feed this directly into a POST /contacts endpoint without any transformation code.

Edge cases, handled

Quoted fields with commas and newlines

Properly handles RFC 4180 quoted fields — so "Smith, John" stays as one field and doesn't split on the comma.

Different delimiters

The delimiter is auto-detected (comma, semicolon, tab, pipe). You can override it manually if the detection gets it wrong.

No header row

Toggle off 'First row is headers' and the converter uses array indices as keys (field_0, field_1, …) rather than crashing on a headerless file.

Frequently asked questions

How does it handle dot-notation headers? Does it go multiple levels deep?

Yes. `billing.address.city` produces `{ billing: { address: { city: '...' } } }`. Any depth works, following the same dot-separated path logic used when converting in the other direction.

What format does the JSON come out in — array or object?

An array of objects by default, which is the most common format APIs expect. Each CSV row becomes one object in the array. If you need a keyed object (a map) instead of an array, you can specify a key column and the output becomes `{ [keyValue]: { ...row } }`.

My CSV has 50,000 rows. Will this work?

Yes. The CSV parser (PapaParse) is built to handle large files and streams the parsing in chunks. 50K rows typically processes in under a second in a modern browser.

Numbers are coming out as strings in my JSON. How do I fix that?

Make sure 'Infer types' is turned on (it is by default). If a column is entirely numeric, it will be cast to a number. If there are any non-numeric values in the column — even a header that looks like a number — it stays as a string to be safe.