Cloud Parts

TOML

A minimal configuration format with explicit types that maps unambiguously to a hash table; the language of Cargo.toml and pyproject.toml.

What it is
File formats (text and markup)
Type
Open source
Made by
toml-lang project, started by Tom Preston-Werner (open specification)
License
MIT (the specification repository)
Facts checked
6 October 2026

What it is

A TOML file is a list of key = value lines grouped under [table] headers, which become nested hash tables when parsed; [[name]] starts another entry in an array of tables, and dotted keys such as server.port = 8080 are shorthand for nesting. Every value has an explicit type you can see: strings are always quoted, and the other types are integers, floats, booleans, arrays, inline tables and four date and time types, from offset date-times to local times. Because nothing is guessed, country = NO is a syntax error, not false. Files must be UTF-8, keys are case-sensitive, # starts a comment, and defining the same table twice is an error.

The spec is maintained in the toml-lang/toml repository on GitHub under the MIT licence, with implementations in most languages. Version 1.0.0 (January 2021) was the first stable release; 1.1.0 (December 2025) allows newlines and trailing commas in inline tables, makes seconds optional in times and leaves integer size up to implementations, recommending at least 64 bits. Rust’s Cargo reads Cargo.toml, Python packaging reads pyproject.toml, and Python has shipped a read-only parser, tomllib, since 3.11; the 3.15 release candidates move it to TOML 1.1.

Why teams pick it

  • No implicit typing: strings are quoted and dates are a real type, so values mean what they look like
  • Comments and a flat, INI-like look make it easy to edit by hand
  • Maps unambiguously to a hash table, and redefining a key or table is an error rather than a silent override
  • The standard for Rust (Cargo.toml) and Python packaging (pyproject.toml), with a parser in Python’s standard library

Watch out for

  • Deeply nested data gets verbose: every level needs a dotted header or an inline table, so it suits configuration, not data exchange
  • No anchors, references or includes; repeated settings are written out again
  • No schema language in the spec, so validation depends on each tool
  • Python’s tomllib can only read; writing, or editing a file while keeping its comments, needs a third-party library
  • 1.1.0 syntax such as multi-line inline tables fails in parsers that only implement 1.0.0, including Python up to 3.14

Alternatives

What all text and markup have in common →

How it fits with other technologies

Reading a pyproject.toml-style file with Python’s tomllib · python

import tomllib  # Python 3.11+, read-only

doc = """
[project]
name = "ingest-worker"
version = "1.4.0"
requires-python = ">=3.11"
dependencies = ["httpx>=0.27", "pyarrow>=17"]

[tool.ingest]
batch_size = 5_000
started = 2026-10-06T09:00:00Z
country = "NO"   # strings are always quoted, so nothing is guessed
"""
cfg = tomllib.loads(doc)
print(cfg["tool"]["ingest"])
# {'batch_size': 5000, 'started': datetime.datetime(2026, 10, 6, 9, 0, tzinfo=datetime.timezone.utc), 'country': 'NO'}

tomllib.loads("country = NO")          # TOMLDecodeError: Invalid value
tomllib.loads("[a]\nx = 1\n[a]\ny = 2")  # TOMLDecodeError: Cannot declare ('a',) twice

JSON, YAML, TOML and XML side by side#

Four text formats for structured data. They overlap, but each grew up around a different job, and that shows in what they leave out.

JSONYAMLTOMLXML
Current specRFC 8259 and ECMA-404 (both December 2017)YAML 1.2.2 (October 2021), a revision of 1.2 from 2009TOML 1.1.0 (December 2025)W3C XML 1.0, Fifth Edition (November 2008)
CommentsNone# to the end of the line# to the end of the line<!-- … -->
Built-in value typesString, number, boolean, nullNull, boolean, integer, float and string in the recommended core schema; others through tagsString, integer, float, boolean, offset and local date-times, dates and timesNone: content is text until a schema gives it types
NestingObjects and arraysMappings and sequences; anchors and aliases reuse a nodeTables, arrays, inline tables and arrays of tablesElements with attributes; namespaces mix vocabularies
Schema languageJSON Schema, a separate spec (latest 2020-12)None; the spec’s “schemas” only decide how unquoted values are typedNone in the specDTDs (part of XML 1.0), W3C XML Schema (XSD), RELAX NG
Typical useWeb API bodies; JSON Lines logs and eventsKubernetes manifests, GitHub Actions workflows, Compose filesCargo.toml, pyproject.toml, Telegraf configOffice documents, SVG, RSS and Atom feeds, SOAP, the S3 API
  • Each cell is taken from the format’s own specification, and typical uses from the documentation of the tools named. The same table appears on the JSON, YAML, TOML and XML pages.

See it in a real stack

No architecture uses TOML yet. Drop it into the playground and wire it up yourself.Open playground →
Where it came from2013–2025

In February 2013 Tom Preston-Werner, then GitHub’s co-founder and CEO, made the first commit to a small spec he called Tom’s Obvious, Minimal Language. The README explained why: “we need a decent human readable format that maps to a hash and the YAML spec is like 80 pages long and gives me rage. No, JSON doesn’t count. You know why.” Version 0.1.0 was tagged that March.

Rust’s package manager, Cargo, adopted it for Cargo.toml. In 2016, PEP 518 chose TOML for Python’s new pyproject.toml because it was human-usable, flexible, came from a standard and wasn’t overly complex like YAML, noting that the Rust community was “quite happy” with the choice. After years of 0.x releases and three release candidates, TOML 1.0.0 shipped in January 2021, and Python 3.11 added tomllib the next year. TOML 1.1.0 followed in December 2025, relaxing inline tables and date-time syntax.

Why it’s built this way

Map unambiguously to a hash table
The stated objective from the first README. Every key path has one meaning, so defining a key or table twice is an error instead of a silent override.
Explicit types, with first-class dates
The first example carried the comment “First class dates? Why not?”. Quoting every string means a parser never has to guess, which avoids YAML’s implicit-typing surprises.
Comments from the start
TOML’s own site says “all config files should support comments”, and the example in the very first README opened with one.

Timeline

  1. 2013

    Tom Preston-Werner starts TOML in February; v0.1.0 tagged in March

  2. 2016

    PEP 518 picks TOML for pyproject.toml

  3. 2021

    TOML 1.0.0, the first stable version (January)

  4. 2022

    Python 3.11 ships tomllib, a read-only TOML parser (October)

  5. 2025

    TOML 1.1.0 adds multi-line inline tables and optional seconds (December)

Sources29 · facts checked 6 October 2026

Improve this page on GitHub