Web & APIs · 4 min read
TOML Explained: The Config Format Behind Cargo and pyproject
If you have touched Rust's Cargo.toml, Python's pyproject.toml, Hugo, or Netlify configuration, you have met TOML. It was designed to be an obvious, minimal config format that maps cleanly onto a dictionary.
Try it yourself with the related tool.
Convert TOML and JSON →Advertisement
Keys, values, and types
A TOML file is a list of key = value pairs. Values are typed: strings in quotes, integers, floats, booleans, arrays in square brackets, and real dates and times such as 1979-05-27T07:32:00Z. Comments start with # — something JSON does not allow at all.
Tables give structure
A header like [server] starts a table, and the keys below it belong to it. Dotted headers such as [server.tls] create nested tables. A double-bracket header [[plugins]] adds an item to an array of tables, which is how TOML expresses lists of objects. Short tables can also be written inline: point = { x = 1, y = 2 }.
Compared with YAML and JSON
Unlike YAML, indentation carries no meaning, and there are no surprising conversions — no stays a string. Unlike JSON, it supports comments and is pleasant to hand-edit. The trade-off is that deeply nested data becomes verbose, so TOML suits flat-ish configuration better than large data documents.
Common gotchas
A key cannot be defined twice, and a table cannot be declared twice. Keys defined after a table header belong to that table, so top-level keys must come before the first header. Converting to JSON is lossless except for dates, which JSON can only represent as strings.
