Skip to content

TOML

TOML, "Tom's Obvious, Minimal Language," is a configuration format designed to be easy to read and easy to map to a hash table. It is used in Python packaging, tool configuration, and many application configs where a clean key/value structure is more important than hierarchy-heavy markup.

Quick Reference

Construct Example
Key/value name = "bert"
String msg = "hello"
Integer epochs = 10
Float lr = 0.001
Boolean debug = true
Array tags = ["nlp", "ml"]
Inline table model = { name = "bert", layers = 12 }
Section [training]
Dotted key training.lr = 0.001
Multiline string prompt = """..."""

Why TOML

TOML is popular when you want: - A clear, explicit config file - Less ambiguity than YAML about types - Easier authoring than JSON for humans - A format that maps cleanly to dictionaries

It is especially common in Python tooling and project configuration.

Basic Syntax

name = "my-model"
version = "1.0.0"
active = true

Rules: - Use = for assignment. - Strings are usually quoted. - Booleans are true or false. - Lines are generally key/value or section headers. - Comments start with #.

Strings

label = "training"
description = 'single-quoted form'

Basic strings use double quotes. Literal strings use single quotes and treat content more directly, with fewer escape sequences.

Multiline basic strings:

prompt = """
You are a helpful assistant.
Answer concisely.
"""

Multiline literal strings:

note = '''
Do not change this text.
'''

Choose quoting style based on whether you need escapes or want raw text.

Numbers

epochs = 10
lr = 0.001
penalty = 1.5e-3

Integers and floats are distinct. Scientific notation is supported for floats.

Be careful when a value should be a string but looks like a number:

version = "1.2.0"

Booleans

debug = true
enabled = false

Only lowercase true and false are the standard boolean forms in TOML.

Arrays

tags = ["nlp", "transformers", "embeddings"]

metrics = [0.82, 0.79, 0.81]

Arrays can contain mixed types in some cases, but homogeneous arrays are clearer.

Array of tables is a very useful TOML pattern:

[[layers]]
name = "conv1"
units = 64

[[layers]]
name = "conv2"
units = 128

Each [[layers]] block is a separate table in an array of tables.

Tables and Sections

A section groups keys:

[training]
lr = 0.001
epochs = 20
batch_size = 64

Accessed in Python as nested keys, typically config["training"]["lr"].

Dotted keys are another way to express structure:

training.lr = 0.001
training.epochs = 20

Both forms are equivalent in meaning, though the section header form is usually clearer for larger blocks.

Inline Tables

model = { name = "bert", layers = 12, hidden = 768 }

Inline tables are compact but can become hard to read if overused. Use them for short, simple groupings.

Nested Structure

[model]
name = "bert"

[model.params]
layers = 12
hidden = 768
dropout = 0.1

This creates a nested mapping without repeating dotted keys everywhere.

Common Configuration Pattern

[package]
name = "ml_pipeline"
version = "0.1.0"

[dataset]
train = "data/train.csv"
val = "data/val.csv"
language = "en"

[training]
optimizer = "adam"
 lr = 0.001
epochs = 20

[testing]
timeout = 300
retries = 3

Use sections to separate concerns.

Parsing in Python

With a TOML library:

import tomllib

with open("config.toml", "rb") as f:
    config = tomllib.load(f)

lr = config["training"]["lr"]

Python 3.11+ includes tomllib for reading TOML. For writing, use a separate write-capable library.

For older Python versions, use a third-party parser.

Writing TOML

Example with a write-capable library:

import toml

config = {
    "training": {
        "lr": 0.001,
        "epochs": 20,
    }
}

with open("config.toml", "w") as f:
    toml.dump(config, f)

TOML writing is straightforward for simple mappings. Nested or array-of-table structures can require care depending on the library.

Type Considerations

TOML is more explicit than YAML about several type issues: - Strings are strings. - Booleans are true/false. - Numbers are numbers. - Dates and times have dedicated forms.

That explicitness reduces some surprises, but it does not eliminate all of them. A value like 1.0 is still a float, and 1 is still an integer.

Common Mistakes

  • Using YAML-style indentation rules in TOML.
  • Forgetting the [section] header when you mean to create a table.
  • Treating dotted keys and section headers as interchangeable in style when one is clearer.
  • Letting a value that should be a string parse as a number.
  • Using array of tables when a simple array or table would be clearer.
  • Overusing inline tables for large structures.
  • Assuming comments or ordering carry meaning for the parser beyond what the format actually supports.

Validation Mindset

TOML is good for explicit config, but still validate: - Required keys exist. - Types are what you expect. - Numeric values are in range. - Paths and identifiers are present and valid. - Array of tables contains the right number of entries.

TOML vs YAML vs JSON

Format Human-friendly Type explicitness Nested structure
TOML Good for config Fairly explicit Sections and dotted keys
YAML Very readable Can infer types Indentation-based
JSON Verbose for humans Explicit Braces and commas

TOML is often the best fit for config files that should be readable, explicit, and mapping-oriented.

  • yaml — another common config format
  • python-dotenv — environment-based configuration
  • make — running tools whose config may be TOML-backed
  • curl — testing services that may serve or consume config
  • ssh — remote configs and deployment

Official Documentation

  • TOML specification
  • Your TOML parser or library documentation
  • Tool-specific TOML schema docs when they exist

TOML's main advantage is clarity. Use it when clarity and explicit mapping matter more than compactness.

Last Updated

2026-09-06 — Initial version.