Converting Between JSON, YAML, TOML, XML and CSV
After reading this you will know which of the five formats can hold which kinds of data, why some conversions lose information, and how to read the notes the converter shows when it has to approximate something.
What the converter does and one example
The tool reads one data format and writes another. You paste JSON, YAML, TOML, XML or CSV, choose a target, and get the same data in the new shape. All five formats describe the same underlying idea: a tree of values made of strings, numbers, booleans, nulls, ordered lists and named maps. Converting between them means mapping one format's spelling of that tree onto another's.
Here is the hook. This JSON:
{"name": "Ada", "langs": ["ml", "toml"], "active": true}
becomes this YAML:
name: Adalangs: - ml - tomlactive: true
Same three keys, same array, same boolean. Nothing was lost because JSON and YAML share the same value model almost exactly. The hard cases start when the two formats disagree about what a value can be, and that is where the notes matter.
The five value models, side by side
Every conversion succeeds or fails on one question: can the target format represent this value at all? The formats differ in three ways that cause almost all the trouble.
- Typed scalars
- JSON, YAML and TOML distinguish numbers, booleans and null from strings. XML and CSV do not: every leaf is text. Reading
truefrom CSV gives you the string"true", not a boolean. - Named maps versus ordered rows
- JSON, YAML, TOML and XML are trees of named keys. CSV is a flat table of rows and columns. A tree deeper than one level has no natural CSV form.
- Native dates and attributes
- TOML has a real date type (
2024-01-30). XML has attributes (<user id="7">) that sit outside the element text. JSON has neither, so both get flattened to strings or extra keys.
The table below shows what each format can hold. A check means the type survives a round trip through that format without a note.
| Type | JSON | YAML | TOML | XML | CSV |
|---|---|---|---|---|---|
| String | yes | yes | yes | yes | yes |
| Number | yes | yes | yes | text | text |
| Boolean / null | yes | yes | yes | text | text |
| Nested map | yes | yes | yes | yes | no |
| Date | string | yes | yes | text | text |
When to use it, and when not
Use the converter when you need to move config or fixture data between tools that expect different formats. A Rust project reads TOML, a Kubernetes manifest is YAML, a browser fetch returns JSON, a spreadsheet exports CSV. Converting by hand is slow and error prone once a file passes about 20 lines.
Do not use it as a schema translator. It moves values, not meaning. If your XML uses attributes to mark units and your JSON consumer expects those units as a suffix on the value, no format converter will do that reshaping. Write a small script instead.
CSV is the one format that cannot hold a tree. If your JSON has any nested object or array of objects, converting to CSV will either flatten keys with a separator like address.city or drop the structure. Check the note the tool prints before you trust the output.
The rule that predicts every lossy conversion
You can predict whether a conversion loses information without running it. Let the source type set be the kinds of values your document uses, and let the target type set be what the target format supports. The conversion is lossless only when the source set fits inside the target set.
Here S is the set of value kinds in your source document (strings, numbers, booleans, dates, nesting depth) and T is the set the target format can express. When S \subseteq T holds, every value has an exact home. When it does not, each value kind in S but not in T forces an approximation.
Worked count: a TOML document using strings, integers and one date has S = \{\text{string}, \text{int}, \text{date}\}, three kinds. JSON supports T = \{\text{string}, \text{int}, \text{float}, \text{bool}, \text{null}, \text{array}, \text{object}\}. The date is not in T, so exactly one kind is lost: the date becomes a string. Two of three kinds survive untouched, so the loss is narrow and the tool flags only the date.
A worked example: JSON to CSV and back
Flattening the demo record
Start with the demo JSON, an array of two records:
[{"id": 1, "name": "Ada", "tags": ["ml"]}, {"id": 2, "name": "Grace", "tags": ["cobol","navy"]}]
- The converter finds an array of objects, which maps to CSV rows. It collects every key across all records:
id,name,tags. That is 3 columns. - Row 1 has
tagsequal to["ml"], an array. CSV has no array type, so the tool joins it into a single cell asmland records a note. - Row 2 has
["cobol","navy"]. Joined with a comma it would collide with the CSV delimiter, so the cell is quoted:"cobol,navy". - The result is 3 rows total: 1 header plus 2 data rows.
The CSV:
id,name,tags1,Ada,ml2,Grace,"cobol,navy"
Now convert that CSV back to JSON. The id cells come back as strings "1" and "2", not numbers, because CSV carries no type. The tags column comes back as the string "cobol,navy", not an array. Two facts were lost on the round trip: numeric type and array structure. That is S \not\subseteq T in action, twice.
Reading the loss notes
The tool prints one note per approximation. Each note names the value, the source type and what it became. The chart below counts how many of the demo record's values survive each target format cleanly, out of the 8 leaf values in the two-record array (2 ids, 2 names, 3 tag strings, plus the array structure counted once per record).
Read the notes as a checklist, not a warning to ignore. If a note says a date became a string, and your consumer sorts dates, that string still sorts correctly in ISO 8601 form (2024-01-30 sorts before 2024-02-01). If a note says a number became text, arithmetic downstream will break until you cast it back.
Common mistakes
Four errors account for most surprises.
- Trusting CSV numbers. After a round trip through CSV,
1is the string"1". Re-cast before doing math. - Assuming XML preserves order and type. XML keeps element order but turns every value into text and hides attributes. A JSON boolean
truebecomes the texttrue, indistinguishable from a string. - Feeding CSV with ragged rows. If row 3 has 4 fields but the header has 3, the parser either drops the extra or errors. Fix the source, do not trust silent truncation.
- Expecting YAML anchors to survive. A YAML anchor and alias (
&a/*a) is expanded into a full copy when converted to JSON, because JSON has no reference mechanism. Two aliases become two independent copies.
Before converting a large file, convert a 3-line sample first and read every note. The note set for the sample usually predicts the note set for the whole file, since loss depends on value kinds, not on row count.
Related tools
Once your data is JSON, the JSON Formatter & Validator will pretty-print it, validate it and let you query it with JSONPath. To compare two JSON documents structurally, for instance a before and after of a conversion, use the JSON Diff. If you are escaping tricky string values by hand, the String Escaper handles JSON, shell and regex escaping. For matching or extracting fields with patterns, the Regex Tester shows what a pattern captures, and the SQL Formatter tidies queries built from converted data.
Frequently asked questions
Why does my number turn into a string after converting to CSV?
CSV has no types. Every cell is text. The converter cannot tell a number from a string that looks like a number, so 42 and "42" both write as 42 and both read back as text. Cast to a number in the consuming code.
Can I convert a deeply nested JSON object to CSV?
Not without flattening. CSV is a flat table. The tool will either join nested keys with a separator (user.address.city) or drop the nesting and print a note. If your data has more than one level, prefer JSON, YAML or TOML as the target.
Are YAML and TOML conversions reliable?
Yes. YAML is parsed with js-yaml and TOML with smol-toml, both well-tested libraries loaded on demand from a CDN. The parsing itself is not the weak point; the loss comes from type differences between formats, which the notes flag.
Does my data leave my browser?
No. The conversion runs entirely in your browser. Nothing you paste is uploaded, so you can convert secrets and internal config safely.
How do XML attributes convert to JSON?
JSON has no attribute concept. The converter usually moves an attribute like id="7" into a key, often prefixed (@id) or merged as a plain key, and records a note. Converting back does not always restore it as an attribute, so an XML round trip through JSON can move data from an attribute into element text.