T tomlkit·org
Inspect Formatter Validator Convert TOMLJSON JSONTOML TOMLYAML YAMLTOML INITOML TOMLINI .envTOML TOML.env TOMLTS Transform Sort keys Flatten Minify Compare Diff Merge

TOML Flattener

updated 8 June 2026

Flatten a nested TOML document to a list of dotted-key assignments — one key per line. Easier to grep, easier to script against, easier to compare visually.

What this tool does

It parses a TOML document, walks the whole value tree, and emits one line per leaf value as path = value — where the path is the chain of table and key names joined by a separator. [server.tls] enabled = true becomes server.tls.enabled = true. The output is itself a flat TOML document: every line is a dotted-key assignment, which TOML 1.0 accepts at the top level.

The intent it closes: "I have a nested config and I need every setting on its own greppable line — or I have a flat dotted-key dump and I need it back as nested tables." The same widget does both directions, so it feeds grep and diff, a feature-flag or key-value store that wants flat keys, and migrations where you have to audit which keys exist before you move them.

One thing to know up front: this is a parse-and-re-emit flow, so comments are not carried through in either direction. The tree the parser builds has no place for them.

When you'd reach for it

  • Grep one subtree of a big config. Flatten with the default dot separator, then grep "database\." over the result — every nested key is now a single literal line.
  • Diff two configs without indentation noise. Flatten both sides and compare; reordered tables and changed nesting collapse to ordinary line-level changes.
  • Feed a flat key-value store. Pick the __ or / separator to match the namespace convention your feature-flag system or KV store expects.
  • Audit array contents key by key. Leave Arrays on key.0, key.1 so each element gets its own path, or switch to key[0] for bracket-style indices.
  • Strip arrays entirely. Set Arrays to Drop to list only the scalar leaf keys when arrays are noise for what you're auditing.
  • Rebuild nested TOML from a flat dump. Switch Direction to Unflatten and paste dotted-key lines — the tool reassembles the nested tables.

How flattening works

One click of Flatten runs three stages. Unflatten reverses them.

1. Parse the input

The input is parsed as TOML 1.0 — the same parser the rest of the site uses. If it isn't valid TOML, the status bar shows the parse error and no output is written. Dotted keys, nested tables, and arrays-of-tables all collapse into one value tree before anything is emitted.

2. Walk to the leaves

The tree is walked depth-first. Each nested table extends the path by the Separator; a scalar (string, number, boolean, date) ends a path and becomes one output line. Arrays are handled by the Arrays policy. An empty table or empty array is itself a leaf — it is emitted as path = {} or path = [] rather than vanishing.

3. Emit one line per path

Each leaf is written as path = value using TOML scalar formatting: strings are quoted, numbers and booleans are bare, dates are written in TOML datetime form. Lines come out in the order the walk reached them, joined by newlines with a trailing newline at the end.

Unflatten (reverse)

With Direction on Unflatten, the tool parses your input as TOML, then splits each top-level key on the Separator and rebuilds the nested objects — server.tls.enabled = true becomes a [server.tls] table again. The result is re-emitted as canonical nested TOML. The root of the input must be a table of dotted keys; if it isn't, you get Reverse: input must be a TOML table of dotted keys.

Options reference

Direction

Flatten (default) turns nested TOML into dotted-key lines. Unflatten (reverse) does the opposite: it reads dotted-key lines and rebuilds nested tables. Both directions split and join paths on the same Separator, so set it to match whatever produced your flat input.

Separator

The string joining path segments. . (dot) is the default and produces ordinary dotted TOML keys (server.tls.enabled) — the most reversible choice, since TOML reads dotted keys natively. __ (double underscore) suits environment-variable-style namespaces; / (slash) suits path-like KV stores. Whatever you pick is used both to build paths when flattening and to split them when unflattening.

Arrays

How array values are rendered when flattening. key.0, key.1, … (default) gives each element its own path using the separator. key[0], key[1], … uses bracket indices instead — note the brackets are literal regardless of the separator you chose. JSON-encoded inline leaves the whole array on a single line as one inline TOML array rather than expanding it into per-index keys. Drop skips arrays entirely, so only scalar leaves remain. This option has no effect when unflattening.

Output

  • Shape (flatten): one path = value line per leaf. The whole thing is a valid flat TOML document of dotted-key assignments.
  • Shape (unflatten): canonical nested TOML with [section] headers, rebuilt from the dotted keys.
  • Values: strings quoted, numbers and booleans bare, dates in TOML datetime form — produced by the same scalar writer the rest of the site uses.
  • Comments: not preserved in either direction. The parser doesn't carry them into the tree.
  • Encoding and line endings: UTF-8, LF, with a trailing newline.
  • Download: flat.txt, content type text/plain;charset=utf-8.

Example

Input:

[server]
host = "0.0.0.0"
port = 8080

[server.tls]
enabled = true
cert = "/etc/ssl/cert.pem"

[database]
url = "postgres://localhost/app"
pool = 10

Output (defaults — Flatten, dot separator, indexed arrays):

server.host = "0.0.0.0"
server.port = 8080
server.tls.enabled = true
server.tls.cert = "/etc/ssl/cert.pem"
database.url = "postgres://localhost/app"
database.pool = 10

Each [section] header has been folded into the key path, and every leaf sits on its own line. Run that output back through with Direction set to Unflatten and you get the nested tables again.

Recipes by intent

Grep one section of a large config

Flatten with the . (dot) separator, copy the output, and grep "database\.". Every key under [database] — however deeply nested — is now a single line you can match with one pattern.

Produce environment-variable-style keys

Set Separator to __. Paths come out as server__tls__enabled, the convention many config loaders use to map env vars onto nested settings. (For a full .env file with uppercased keys, the dedicated TOML → .env tool is a closer fit.)

Audit only the scalar keys, ignoring arrays

Set Arrays to Drop. The output lists every scalar leaf and nothing else — handy when you're cataloguing which settings exist and array contents would only clutter the list.

Rebuild nested TOML from a flat dump

Switch Direction to Unflatten, make sure Separator matches the one in your flat input, and paste the dotted-key lines. The tool splits each key and re-emits proper nested tables.

Limits and performance

  • In-memory. The input string, the parsed tree, and the flat output all sit in memory at once. Config-sized files are instant; multi-megabyte TOML takes a moment to parse and walk.
  • The textarea is the slow bit on huge output. Tens of megabytes of flat lines can lag the right-hand pane after the work itself finishes — use Download .txt instead of Copy.
  • Comments don't survive. Parse-then-emit drops them in both directions; keep your annotated source file if comments matter.
  • Separator collisions. If a key name already contains your chosen separator, unflattening will split inside that name and rebuild the wrong nesting. Pick a separator that doesn't appear in your keys.

Errors and how to fix them

Reverse: input must be a TOML table of dotted keys.

You're in Unflatten mode and the input didn't parse to a top-level table — for example it was empty or a bare value rather than a set of key = value lines. Unflattening expects a flat TOML document of dotted keys, which is exactly what Flatten produces. Check that the pane really holds dotted assignments and that Direction is set the way you mean.

Parse error / the status bar goes red on click

The input isn't valid TOML 1.0. Common causes: unclosed quotes, an array that opens with [ but never closes, a missing =, or a duplicate key inside the same table. The TOML Validator points at the exact line.

Unflattening put keys in the wrong place

Almost always a separator mismatch: the flat input was built with one separator and you unflattened with another, or a key name contains the separator character and got split inside it. Set Separator to match the input and avoid separators that appear inside key names.

My # comments disappeared

Expected. The parser doesn't carry comments into the value tree, so neither flattening nor unflattening can re-emit them. Keep the original file as your source of truth and run a copy through the tool.

FAQ

Can I round-trip flatten then unflatten?

Yes, as long as you use the same separator both ways and no key name contains that separator. Flatten produces dotted-key lines; switching Direction to Unflatten rebuilds the nested tables from them. Comments are the one thing that won't survive the trip.

How are arrays handled when I flatten?

It depends on the Arrays option. By default each element gets an indexed path (tags.0, tags.1); key[0] uses bracket indices; JSON-encoded inline keeps the array on one line as an inline TOML array; Drop omits arrays so only scalar leaves remain.

Is the flat output valid TOML?

Yes. Every line is a dotted-key assignment, which TOML 1.0 supports at the top level, so you can paste the flat output straight into the formatter or the validator.

Is my data uploaded?

Never. Parsing and emitting both run entirely in your browser. You can go offline after the page loads and the tool still works — safe for configs holding secrets or connection strings.