Est. 2013 Beginner

TOML

A minimal, human-readable configuration file format created by GitHub co-founder Tom Preston-Werner, designed to map unambiguously to a hash table and now used for Rust's Cargo manifests and Python's pyproject.toml.

Created by Tom Preston-Werner

Paradigm Declarative: data serialization / configuration format
Typing Strongly typed values (String, Integer, Float, Boolean, Date-Time, Array, Table)
First Appeared 2013
Latest Version TOML 1.1.0 (December 2025)

TOML — short for Tom’s Obvious, Minimal Language — is a configuration file format designed to be easy for humans to read and write while mapping unambiguously to a hash table (a dictionary of key-value pairs). Created by Tom Preston-Werner, co-founder of GitHub, TOML sits alongside JSON and YAML in the family of data-serialization formats, but it stakes out a specific niche: configuration files that people edit by hand. Where JSON is verbose and unfriendly to comments, and YAML is powerful but famously subtle in its edge cases, TOML aims to be obvious — a format whose meaning you can predict just by looking at it.

Strictly speaking, TOML is not a programming language: you do not execute a TOML file. It is a declarative data format, closer to INI or JSON than to Python or Rust. But it has become such a pervasive part of the modern software toolchain — powering Rust’s Cargo.toml, Python’s pyproject.toml, and countless other tools — that it belongs in any survey of the notations developers work with every day.

History & Origins

TOML was introduced in 2013 by Tom Preston-Werner. Preston-Werner had already left a deep mark on developer culture as a co-founder of GitHub and the creator of the Jekyll static site generator and the Semantic Versioning specification. TOML grew out of a recurring frustration: the humble INI file was pleasant to read but had no formal specification, so every parser interpreted it slightly differently, and there was no agreed way to represent nested structures, arrays, or typed values like dates and numbers.

The first public specification, version 0.1.0, appeared in early 2013. The name was originally floated, half-jokingly, as “Tom’s Own Markup Language,” but it was soon rebranded as the more descriptive “Tom’s Obvious, Minimal Language.” The goal was explicit from the outset, stated at the top of the spec: TOML should be a minimal format that is obvious to read, maps cleanly onto a hash table, and is easy to parse into data structures across many programming languages.

From 0.x to a Stable Standard

For its first several years, TOML lived in the pre-1.0 world where the specification could still change. Important milestones during this period included 0.4.0 (2015), which solidified inline tables and arrays of tables, and 0.5.0 (2018), which added dotted keys and richer date and time types. The long march toward stability culminated in the first release candidate, 1.0.0-rc.1, in April 2020, and finally TOML 1.0.0 in January 2021 — a frozen, stable specification that implementers and users could rely on for the long term.

In December 2025, the format received its first post-1.0 revision, TOML 1.1.0, which relaxed a few of the stricter rules — permitting multi-line inline tables with trailing commas, adding new string escape sequences, and making seconds optional in date-time values.

Design Philosophy

TOML’s design is guided by a small set of firm principles:

  • Obvious over clever. A reader who has never seen TOML should be able to guess what a file means. Sections are marked with [headers], values follow key = value, and comments start with #.
  • A clean map to a hash table. Every valid TOML document corresponds to exactly one dictionary of keys and values. This makes TOML predictable to parse and to generate.
  • Minimal, but typed. Unlike INI, where everything is a string, TOML values carry real types — integers, floats, booleans, strings, and — distinctively — first-class dates and times.
  • Written for humans first. TOML optimizes for the person editing a config file, not for machine-to-machine data interchange (a role where JSON usually wins).
  • Unambiguous by specification. TOML has a formal grammar (expressed in ABNF), so conforming parsers agree on what a document means — the very consistency that ad-hoc INI variants lacked.

Key Features

Basic Key-Value Pairs and Comments

1
2
3
4
5
# This is a comment
title = "TOML Example"
enabled = true
port = 8080
pi = 3.14159

Tables (Sections)

Tables group related keys under a bracketed header, and dotted names create nesting:

1
2
3
4
5
6
[server]
host = "localhost"
port = 5432

[server.credentials]
user = "admin"

Arrays and Arrays of Tables

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
ports = [8000, 8001, 8002]
hosts = ["alpha", "omega"]

[[products]]
name = "Hammer"
sku = 738594937

[[products]]
name = "Nail"
sku = 284758393

First-Class Dates and Times

One of TOML’s signature features is native support for dates and times, following RFC 3339:

1
2
3
launch_date = 2013-02-23
last_modified = 2026-07-09T09:30:00-06:00
local_time = 07:32:00

Strings

TOML offers basic strings (with escapes), literal strings (no escaping, single quotes), and multi-line variants:

1
2
3
4
5
6
path      = 'C:\Users\nodejs'          # literal string, backslashes preserved
greeting  = "Hello,\nWorld!"           # basic string with escapes
multiline = """
Line one
Line two
"""

Evolution

VersionApprox. dateHighlights
0.1.02013First public specification
0.4.02015Inline tables, arrays of tables
0.5.02018Dotted keys, local date/time types
1.0.0-rc.1April 2020First release candidate
1.0.0January 2021First stable, frozen specification
1.1.0December 2025Multi-line inline tables, new escapes, optional seconds

The trajectory from 0.1.0 to 1.0.0 spanned nearly eight years — an unusually deliberate pace that reflected a commitment to getting the format right before declaring stability. A visible tension in the ecosystem is version adoption: because so much tooling standardized on TOML 1.0.0, many parsers and consumers (including parts of the Rust and Python ecosystems) still target 1.0.0 even after 1.1.0’s release, so authors are often advised to stick to 1.0.0 features for maximum compatibility.

Current Relevance

TOML’s rise is inseparable from the rise of the tools that adopted it. Rust’s Cargo made Cargo.toml the face of every Rust project, and Python’s packaging ecosystem made pyproject.toml — standardized by PEP 518 (2016) and PEP 621 (2020) — the modern home for build configuration, project metadata, and tool settings. The endorsement was cemented in 2022 when Python 3.11 added the tomllib module to its standard library (via PEP 680), giving every Python installation a built-in TOML parser.

Beyond those flagships, TOML appears in Julia package environments, Hugo and other static site generators (including this site’s front matter), Netlify and CI configuration files, and a long tail of developer tooling. Mature, well-tested parsers exist for essentially every major programming language, and the specification maintains an extensive compliance test suite so that implementations can prove their conformance.

Why It Matters

TOML’s significance is less about technical novelty than about taming a mess that everyone had quietly tolerated. For decades, configuration files were an unspecified free-for-all: INI dialects that no two programs read the same way, or JSON pressed into a role — comment-free and comma-fussy — for which it was never designed. TOML offered a middle path: a format with the readability of INI, the typed rigor of JSON, and a real specification behind it.

Its adoption by Cargo and Python’s packaging tools turned TOML from a personal project into de facto infrastructure for two of the most active language communities in software. Today, a developer picking up modern Rust or Python will almost certainly edit a TOML file within their first hour — often without needing to learn anything at all, which is exactly the “obvious” outcome its creator set out to achieve.

Sources

Timeline

2013
Tom Preston-Werner, co-founder of GitHub, publicly introduces TOML and releases the first specification, version 0.1.0
2015
TOML 0.4.0 is released, refining the format with features such as inline tables and arrays of tables
2016
Python's PEP 518 (accepted May 2016) standardizes the pyproject.toml build-system file in TOML format, seeding TOML's role in Python packaging
2018
TOML 0.5.0 is released, adding dotted keys and local date, local time, and local date-time value types
2020
The first release candidate, TOML 1.0.0-rc.1, is published in April, and PEP 621 adopts a standardized [project] metadata table in pyproject.toml
2021
TOML 1.0.0, the first stable specification, is released in January, freezing the language for long-term compatibility
2022
Python 3.11 (released October 24) ships tomllib in the standard library via PEP 680, making TOML parsing available out of the box
2025
TOML 1.1.0 is released in December, allowing multi-line inline tables with trailing commas, new string escape sequences, and optional seconds in date-times

Notable Uses & Legacy

Rust / Cargo

Rust's package manager Cargo uses a Cargo.toml manifest to declare package metadata, dependencies, features, and build profiles, making TOML the everyday configuration format for millions of Rust crates.

Python packaging

The pyproject.toml file, standardized through PEP 518 and PEP 621, is the central configuration file for modern Python projects, declaring build backends, project metadata, dependencies, and tool settings for tools like pip, Poetry, Hatch, and Ruff.

Hugo

The Hugo static site generator supports TOML for site configuration and page front matter, and this very site uses TOML front matter in its content files.

Julia

The Julia language uses Project.toml and Manifest.toml files to describe package environments, dependencies, and exact resolved versions for reproducible builds.

Netlify and CI tooling

Configuration files such as netlify.toml define build commands, redirects, and deployment settings, a pattern echoed across many developer and CI/CD tools that favor TOML's readability.

Language Influence

Influenced By

INI

Running Today

Run examples using the official Docker image:

docker pull
Last updated: