TOML format: a less ambiguous YAML for config files
TOML (Tom’s Obvious Minimal Language) is designed for config files. Less ambiguous than YAML and easier to write than JSON. This article walks through the syntax and use cases.
Basics
# Comments use #
title = "TOML example"
[owner]
name = "Tom Preston-Werner"
created = 1979-05-27T07:32:00-08:00
[database]
server = "192.168.1.1"
ports = [8001, 8001, 8002]
connection_max = 5000
enabled = true Features:
- INI-file feel.
- Sections (tables) via
[name]. - No indentation needed.
- Strict, explicit types.
Types
| Type | Example |
|---|---|
| String | "hello", 'literal' |
| Int | 42, 0xff, 0o77, 0b1010 |
| Float | 3.14, 1e10 |
| Boolean | true, false |
| Datetime | 1979-05-27T07:32:00Z |
| Date | 1979-05-27 |
| Time | 07:32:00 |
| Array | [1, 2, 3] |
| Table | { key = "value" } |
| Array of tables | [[products]] |
String forms
Four kinds:
# Basic (escapes allowed)
str1 = "I'm a "quoted" string"
# Literal (no escapes, single quotes)
str2 = 'C:Users\nodejs\templates'
# Multiline basic
str3 = """
Roses are red
Violets are blue"""
# Multiline literal
str4 = '''
This is
literal
''' Tables (sections)
Hierarchy via [a.b.c]:
[servers.alpha]
ip = "10.0.0.1"
port = 8080
[servers.beta]
ip = "10.0.0.2"
port = 8081 Inline form:
[servers]
alpha = { ip = "10.0.0.1", port = 8080 }
beta = { ip = "10.0.0.2", port = 8081 } Array of tables
List of table values:
[[products]]
name = "Hammer"
sku = 738594937
[[products]]
name = "Nail"
sku = 284758393
color = "gray" In JSON:
{
"products": [
{ "name": "Hammer", "sku": 738594937 },
{ "name": "Nail", "sku": 284758393, "color": "gray" }
]
} Dates
Native date types:
# UTC
date1 = 1979-05-27T07:32:00Z
# Local datetime (no zone)
date2 = 1979-05-27T07:32:00
# Date only
date3 = 1979-05-27
# Time only
time = 07:32:00 Less ambiguous than YAML.
Conversion to JSON
Same data, two formats:
title = "TOML"
[database]
server = "localhost"
ports = [8001, 8002] {
"title": "TOML",
"database": {
"server": "localhost",
"ports": [8001, 8002]
}
} Round-trips cleanly (comments lost in JSON).
TOML vs YAML
| Property | TOML | YAML |
|---|---|---|
| Indentation | None required | Significant |
| Ambiguity | Low | High (Norway problem etc.) |
| Comments | Yes | Yes |
| Date type | Explicit | Yes (impl-dependent) |
| Learning curve | Low | Medium |
| Deep nesting | Awkward | Good |
Choose TOML for config, YAML for deeply structured data.
Where it’s used
Cargo (Rust)
Cargo.toml:
[package]
name = "my-app"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] } Python (pyproject.toml)
Standardized in PEP 518, PEP 621:
[build-system]
requires = ["setuptools >= 61"]
build-backend = "setuptools.build_meta"
[project]
name = "my-package"
version = "1.0.0"
dependencies = [
"requests >= 2.28",
"click >= 8.0"
] Replacing setup.py over time.
Hugo (static site generator)
config.toml (or hugo.toml):
baseURL = "https://example.com"
title = "My Blog"
languageCode = "en"
[params]
description = "Site description" Pitfalls
Duplicate keys are errors
# Error
name = "first"
name = "second" Stricter than YAML or JSON.
Table order
[a]
key = 1
[b]
key = 2
[a.c] # OK — child of [a]
key = 3 But re-opening [a] is forbidden:
[a]
key = 1
[b]
# ...
[a] # Error: already defined
other = 2 String escapes
Basic strings treat \ as special:
# Error (U is reserved)
path = "C:Users"
# OK (literal)
path = 'C:Users'
# OK (escaped)
path = "C:\Users" Use literal strings for Windows paths.
Spec versions
- 0.5.0 (2018) — widely deployed.
- 1.0.0 (Jan 2021) — official release.
- 1.1.0 — proposed extensions.
Use TOML 1.0 for new projects.
Tools
- Official: toml-lang/toml.
- Validation: toml-test.
- Online converters between TOML / JSON / YAML.
Libraries:
- Rust —
toml. - Python —
tomllib(stdlib 3.11+),tomli. - Go —
BurntSushi/toml. - JavaScript —
@iarna/toml,toml. - Java —
tomlj.
When to pick TOML
Good fit:
- Config files (especially technical).
- Package-manager manifests.
- Flat-ish settings.
Poor fit:
- Deeply nested data.
- Streaming pipelines.
- Bulk data transfer.
Summary
- TOML is INI-style, type-explicit config format.
- Used by Cargo, Python’s pyproject.toml, Hugo.
- Stricter than YAML, friendlier than JSON.
- Pick TOML for config; JSON for data interchange.
To convert TOML to JSON, the TOML-to-JSON tool on this site handles the typical cases.