TOML to CSV Converter

Paste a TOML document and get one CSV row per array-of-tables entry — nested tables flattened into dot-notation columns, ragged entries kept whole by a unioned header.

Try:
CSV output

Convert a TOML array-of-tables into a spreadsheet

TOML is a config format, so its repeated [[section]] blocks are really a table in disguise: every [[users]] entry is a record and every key inside it is a field. This tool turns that structure into CSV — one row per entry, one column per key — so you can open a Cargo.toml, a pyproject.toml, a Netlify or Hugo config, or any hand-written TOML data file in a spreadsheet, load it into a database, or diff it against another export.

The header is the union of every key seen across all entries, not just the keys of the first one. Config files are routinely ragged — one server has a region, the next doesn't — and taking the first entry as the schema would silently drop the rest. Missing values become empty cells instead.

Everything runs in your browser through WebAssembly. The TOML you paste is never uploaded.

Worked example

Input:

[[users]]
name = "Ada"
role = "admin"
tags = ["founder", "ops"]

[[users]]
name = "Linus"
role = "dev"

With the defaults (auto-detect table, flatten nested tables, arrays as JSON, union header, comma delimiter, header row on):

name,role,tags
Ada,admin,"[""founder"",""ops""]"
Linus,dev,

Switch Array values to Indexed columns and the same input becomes name,role,tags.1,tags.2 with founder and ops in their own cells — ready to sort and filter.

Nested tables

A sub-table inside an entry has no natural cell to live in, so you choose:

[[servers]]
name = "web-1"
addr = { city = "Berlin", zip = "10115" }

Flattening recurses, so [servers.addr.geo] becomes addr.geo.lat.

Controls and limits

FAQ

What is an "array of tables" and how do I know if my file has one?

It is the repeated double-bracket form: [[users]] written two or more times, each block holding the same kind of keys. That is TOML's way of writing a list of records, and it is the shape that maps cleanly to CSV rows. A single [users] (one bracket) is a plain table and converts to a single row instead.

My file has several `[[...]]` sections. Which one gets converted?

Leave the path blank and the first root-level array-of-tables in document order wins; if there is none at the root, the first nested one is used. To pick a different one, type its dotted path — servers.pool for [[servers.pool]]. If the path doesn't exist, the error message lists every array-of-tables the tool did find, so you can copy the right one.

Why are some cells empty?

Because the header is the union of keys across all entries. If one [[users]] block has a region key and another doesn't, region still becomes a column and the entry that lacks it gets an empty cell. That is deliberate — the alternative is losing data. Use Header columns → First row's keys only if you want the first entry to define a strict schema instead.

Can I convert CSV back to TOML with this?

No, this direction is one-way. It is a reshaper, not a round-trip serializer: comments are gone, and the flattening choices (dot columns, joined arrays) aren't reversible without knowing the original types.

What happens to dates, numbers, and booleans?

They keep their TOML text form. 1979-05-27T07:32:00Z stays exactly that, true stays true, and 1.0 stays 1.0 rather than collapsing to 1. No arithmetic, rounding, locale formatting, or type coercion is applied, so a spreadsheet import sees the same characters that were in the file.

Is my configuration file uploaded anywhere?

No. The converter is compiled to WebAssembly and runs entirely in your browser tab — the TOML never leaves your device, and the page keeps working offline once loaded. That matters here because config files often contain hostnames, internal service names, and other details you don't want pasted into a remote service.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool toml-to-csv '[[users]]
name = "Ada"
role = "admin"
tags = ["founder", "ops"]

[[users]]
name = "Linus"
role = "dev"'

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/toml-to-csv/?input=%5B%5Busers%5D%5D%0Aname%20%3D%20%22Ada%22%0Arole%20%3D%20%22admin%22%0Atags%20%3D%20%5B%22founder%22%2C%20%22ops%22%5D%0A%0A%5B%5Busers%5D%5D%0Aname%20%3D%20%22Linus%22%0Arole%20%3D%20%22dev%22&table=users&nested=flatten&array_format=json&columns=union&delimiter=comma&include_header=true

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.