Cookies for analytics and advertising
We use cookies for analytics and advertising, both sent to Google. Refusing changes nothing you can see.Read the privacy page
TOML
A configuration format that stays readable without YAML’s indentation traps.
TOML
TOML is a plain-text format you can open in any editor. It is used for editing.
The extension is .toml, and the full name is Tom's Obvious Minimal Language. Both matter less than what the file can hold, which is what the rest of this page is about.
It dates from 2013. The specification is TOML 1.0.
Age is worth knowing here for one practical reason: the older a format is, the more programs have had time to learn it.
It is published in full, so anyone can implement it from the document rather than by inspection, which is why it turns up in so many programs and why files written twenty years ago still open. A published specification is not the same thing as a royalty-free one: where a format wraps a codec, the patent licensing is a separate question the standard does not settle.
TOML stores its content exactly. Saving it again changes nothing, so it can be opened, edited and re-saved as often as you like without accumulating damage — which is what makes it a working format rather than a delivery one.
TOML has a comment syntax, which is the difference between a file a person maintains and one a program writes. Comments are the first thing lost converting to a format without them, and nothing warns you.
Visual Studio Code reads it, and so do most programs of the same kind.
If a file will not open, the format is rarely the problem — it is more often that the program predates it. Converting to something older is the reliable way past that, and it is what the rest of this site is for.
No browser reads it.
That is the single most common reason to convert it: not that the format is bad, but that the place you want to show the file cannot read it.
TOML is meant to be opened and changed. Keep the file in this format for as long as the work is going on, and export from it whenever a finished copy is needed.
TOML looks like INI and behaves like a data format. A value written as 30 is an integer, 30.0 is a float, true is a boolean, "30" is a string, and 2026-08-05 is a date — the format defines all of them, so every parser agrees and no program has to guess what the author meant.
That single property is most of the reason it exists. Configuration bugs cluster around exactly this ambiguity: a flag read as the string "false" and found truthy, a version number silently turned into a float, a port number that arrives as text. A format with types removes the whole class.
YAML is more capable and much easier to get wrong, and TOML was written in direct response to that. Structure in YAML is expressed by indentation, so a misplaced space changes the meaning of a document without producing an error, and the file still parses — into something other than what was intended.
Then there is the type inference. Older YAML reads no as a boolean, so a country code, a language field or an answer column becomes false. Version numbers like 1.20 become the float 1.2. A time-like string becomes a sexagesimal number. Each of these has caused real outages. TOML has none of them: structure is explicit, and a value is what its syntax says it is.
Rust put it everywhere first — every Cargo project has a Cargo.toml — and Python followed decisively: pyproject.toml is now the standard place for build configuration, and the language ships a TOML reader in its standard library.
Beyond those, Hugo and several static-site generators, Netlify, Poetry, Ruff, and a steady stream of newer tools that wanted configuration a human could edit without the indentation risk. It has become the default choice for developer-facing configuration in roughly the way YAML became the default for infrastructure.
A bracketed header is a table, which is TOML’s word for a section. Nesting is done with a dot: [tool.ruff.lint] declares a table inside a table inside a table, and the dots are structure rather than part of a name — which is exactly where INI stops and TOML continues.
Double brackets are the part that catches everyone. [[bin]] repeated three times does not redefine a table three times; it declares an array of tables, three entries in a list. It is how you express "several of the same kind of thing" — three binaries, four dependencies, a list of authors — and if a configuration is being silently overwritten rather than accumulated, single brackets where double ones belong is nearly always why.
TOML understands dates and times directly: a date on its own, a time on its own, and a timestamp with or without an offset. They are values in the same way integers are, not strings that something has to parse afterwards.
This is a small feature that removes a persistent annoyance. Configuration containing a release date, an expiry, a cutoff or a schedule no longer needs an agreed string format documented in a comment and reimplemented in every consumer. The format specifies it, and the parser hands back a date.
Deeply nested data. TOML is designed to be flat and readable, and once structure goes three or four levels down the header names become long and the file becomes harder to follow than the JSON it is trying to replace. If your configuration looks like a document tree, it probably wants to be one.
Machine-generated data is the other case. TOML is for files people edit; JSON is for files programs exchange, and it is smaller, faster to parse and supported everywhere. Using TOML as a data interchange format is possible and gains nothing — the readability it optimises for is only worth paying for when a human is reading.
Any text editor, and one with TOML support is worth having for anything substantial — it will show an unterminated string or a malformed table header immediately, where a parser will report it as a failure on a line some distance away.
Two habits prevent most mistakes. Keep every key inside the table header it belongs to, since a key written above the first header lands at the top level and quietly does nothing. And do not quote numbers or booleans: the quotation marks make them strings, the program then compares a string against a boolean, and the setting appears to be ignored for no visible reason.
| Extension | .toml |
|---|---|
| Media type | application/toml |
| First published | 2013 |
| Specification | TOML 1.0 |
Any text editor — it is plain text. An editor with TOML support is worth using for real work, since it flags a malformed table header or an unterminated string where a parser would report a failure several lines away.
TOML makes structure explicit with bracketed headers, where YAML uses indentation that can change meaning invisibly. TOML also has no surprising type inference — YAML famously reads no as false and turns 1.20 into 1.2. TOML is less powerful and much harder to get wrong.
TOML has a specification, real types, defined nesting with dotted table names, arrays and dates. INI has none of these — every value is a string until some program decides otherwise, and every implementation invents its own rules.
An array of tables. Writing [[bin]] three times creates three entries in a list rather than redefining one table three times. If repeated configuration blocks appear to overwrite each other, single brackets where double ones belong is the usual cause.
No. Quoting makes them strings, and the program then compares a string against a number or a boolean and appears to ignore your setting. Write 30, true and 2026-08-05 unquoted — the format understands all three.
For configuration people edit, yes and it is usually better. For data programs exchange, no — JSON is smaller, faster to parse and supported everywhere, and the readability TOML optimises for is only worth paying for when a human is reading the file.