induwara.lk
induwara.lkDeveloper · Browser-only

JSON to CSV, XML, and YAML converter

Paste any JSON to convert it to CSV (RFC 4180), XML (1.0 well-formed), or YAML (1.2 block-style) directly in your browser. Nested objects flatten with a configurable separator. Nothing is uploaded.

By Induwara AshinsanaUpdated May 11, 2026
JSON to CSV / XML / YAML
Runs in your browser
Output format
Delimiter
Options

201 characters, 12 lines.

Round-trip verified — CSV parses back to 2 rows.

Status
Valid · CSV
Round-trip verified
Rows
2
3 columns
Input
201 B
12 input lines
Top level
Array
5 composite nodes

How it works

The input is first parsed with the browser's built-in JSON.parse — the same RFC 8259 / ECMA-404 implementation Node.js and every standards-compliant client use. If parsing fails the converter surfaces the line, column, and byte position of the error, along with a hint about the most likely cause.

CSV output follows RFC 4180. The flatten step walks each top-level record and assembles a column set from the union of all dotted key paths, preserving first-seen order. Nested objects flatten with the chosen separator (default .). Arrays inside a row are JSON-encoded into the cell — exploding them into many columns usually produces unreadable spreadsheets. Fields containing the delimiter, CR, LF, or a double quote are wrapped in double quotes, with internal quotes doubled per the RFC. The line terminator is LF, which works in every modern spreadsheet.

XML output follows W3C XML 1.0. The configurable root tag wraps the entire document. Each JSON object key becomes a child element; each array element becomes a repeated element with the configurable item tag. JSON nulls render as empty self-closing elements (<tag/>). Key names that violate the XML Name production (start char must be a letter or underscore; body chars must be letters, digits, dots, hyphens, or underscores; cannot start with xml) are sanitised. Text content has &, <, and > escaped.

YAML output is a block-style subset of YAML 1.2. Plain (unquoted) scalars are used whenever it's unambiguous; otherwise the value is double-quoted with proper escape sequences (\n, \t, \", and \xHH for control bytes). The emitter quotes strings that would round-trip as a different type under YAML 1.1 (which many parsers still follow): yes, no, on, off, dates like 2026-05-11, and anything that parses as a number. This means the YAML the page emits is safe to feed into Kubernetes, Ansible, and GitHub Actions without losing string types.

Every successful CSV conversion is silently round-trip verified: the emitted CSV is re-parsed with the same RFC-4180 parser and the data-row count must match the number of source records. If it ever doesn't, the page surfaces a warning. This is the credibility check the tool advertises — not just "valid CSV", but "CSV that parses back to the same number of rows."

Worked examples

Flat array of objects → CSV

Input (JSON)

[
  { "name": "Alice", "age": 30 },
  { "name": "Bob",   "age": 25 }
]

Output

name,age
Alice,30
Bob,25

Default options. The header row is the union of all top-level keys, the data rows follow in source order. Open this CSV in Excel or Sheets directly.

Nested object → flattened CSV

Input (JSON)

[
  {
    "user": { "name": "Alice", "age": 30 },
    "city": "Colombo"
  }
]

Output

user.name,user.age,city
Alice,30,Colombo

Nested keys flatten with the chosen separator (default `.`). The column order matches the first-seen path order across all records, which gives stable diffs when the same input runs twice.

Special characters → quoted CSV

Input (JSON)

[
  { "text": "Hello, world", "quote": "She said \"hi\"" }
]

Output

text,quote
"Hello, world","She said ""hi"""

The comma forces quoting on the first field. The double quote inside the second value is doubled per RFC 4180. The output round-trips perfectly through any compliant CSV parser.

Nested JSON → XML

Input (JSON)

{
  "users": [
    { "name": "Alice" },
    { "name": "Bob" }
  ]
}

Output

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <users>
    <item>
      <name>Alice</name>
    </item>
    <item>
      <name>Bob</name>
    </item>
  </users>
</root>

The root and array-item tag names are configurable. Each object key becomes a child element; array elements repeat under the item tag. Text content is XML-escaped.

Config object → YAML

Input (JSON)

{
  "server": { "host": "localhost", "port": 2060 },
  "debug": true,
  "tags": ["next", "tailwind"]
}

Output

server:
  host: localhost
  port: 2060
debug: true
tags:
  - next
  - tailwind

Block-style YAML with 2-space indent. Strings that parse cleanly as plain scalars (like `localhost`) are emitted unquoted; numbers and booleans use their native YAML forms.

Frequently asked questions

Sources & references

Each conversion follows the standard linked above. Specifications last reviewed on 2026-05-11. The source code for the converter is public on this repository; report a divergence and I'll add a regression test the same day.

Related tools

Rate this tool
Be the first to rate

Comments & feedback

Spotted a bug or want an improvement? Tell us — our team reviews every comment, and good ideas get built. Comments are public and anonymous.

Found a bug, edge case, or want to suggest an improvement?

Email me at [email protected] — most fixes ship within 24 hours.