TOML Cheatsheet
Keys and Values
Use this TOML reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
The shape of a TOML file
TOML 1.0.0. Every line is either a comment, a [table] header, or exactly one
key = value pair. Every value needs a key, and every pair lives on one line.
There is no bare value, no anonymous array at the top level, and no way to split a
pair across lines except inside a multi-line string or array.
# a comment runs to end of line title = "TOML Example" enabled = true port = 8080 [owner] name = "Tom Preston-Werner"
Whitespace around = is free, both \n and \r\n are valid line endings, and the
file must be valid UTF-8. A BOM is not part of the spec, and Python's tomllib
rejects one with Invalid statement (at line 1, column 1).
Bare keys
A bare key is A-Za-z0-9_-. That includes all-digit keys, which stay strings.
key = "value" bare_key = "underscores fine" bare-key = "dashes fine" 1234 = "digits fine"
parses to:
{"key": "value", "bare_key": "underscores fine",
"bare-key": "dashes fine", "1234": "digits fine"}Note the key is the string "1234", not the integer 1234.
An empty bare key is not allowed. = 1 is a syntax error.
Quoted keys
Anything else needs quotes, and both string forms work as keys.
"127.0.0.1" = "value" "character encoding" = "value" "ʎǝʞ" = "value" 'literal key' = "value" 'quoted "value"' = "value" "" = "an empty key is legal, but do not"
Basic ("...") quoted keys process escapes. Literal ('...') quoted keys do not,
which is what you want for a key containing a backslash.
Dotted keys
A dot in a key creates nested tables. These two files are identical:
name = "Orange" physical.color = "orange" physical.shape = "round" site."google.com" = true
name = "Orange" [physical] color = "orange" shape = "round" [site] "google.com" = true
Both parse to:
{"name": "Orange",
"physical": {"color": "orange", "shape": "round"},
"site": {"google.com": true}}Whitespace around the dots is ignored, so a . b . c = 1 is the same as
a.b.c = 1. Write it without spaces anyway. Only the last segment is the key,
every earlier segment names a table.
Keys are case sensitive and cannot be redefined
abc = 1 ABC = 2 # a different key, both survive
a = 1 a = 2 # ERROR: Cannot overwrite a value
Python's tomllib reports TOMLDecodeError: Cannot overwrite a value (at line 2,
column 6). There is no last-wins behaviour anywhere in TOML, which is the single
biggest ergonomic difference from YAML. Defining the same table twice is an error
too, and so is turning a defined value into a table.
Extending a dotted-key namespace is fine, as long as you never overwrite a concrete value:
a.b = 1 a.c = 2 # fine, both under [a]
Value types at a glance
| Type | Example |
|---|---|
| string | "basic" · 'literal' · """multi""" · '''multi''' |
| integer | 42 · -17 · 1_000 · 0xFF · 0o755 · 0b1010 |
| float | 3.14 · -0.01 · 5e+22 · inf · nan |
| boolean | true · false (lowercase only) |
| offset date-time | 1979-05-27T07:32:00Z |
| local date-time | 1979-05-27T07:32:00 |
| local date | 1979-05-27 |
| local time | 07:32:00 |
| array | [1, 2, 3] |
| inline table | {x = 1, y = 2} |
| table | [header] |
| array of tables | [[header]] |
True is a syntax error, not a string. So is a bare word: mode = production
fails, it needs quotes. TOML has no null type. To express absence you omit the
key entirely, and the reader supplies a default.
Comments
#starts a comment and runs to end of line. There is no block comment form.A
#inside any string form is literal. Control characters other than tab are not allowed in a comment, which matters only if you paste something odd.