PEP 518 introduced pyproject.toml for build-system declaration; PEP 621 standardized [project] metadata. Today nearly every Python tool — Poetry, Hatch, PDM, ruff, black, mypy, pytest, pytest-asyncio, coverage — reads its config from [tool.<name>]. One file replaces setup.py + setup.cfg + requirements.txt + tox.ini + .flake8.
Cargo.toml — Rust's manifest
Every Rust crate has one. [package], [dependencies], [dev-dependencies], [features], [[bin]], [[bench]]. Cargo's tooling (build, test, publish, doc) reads from this single file. Workspaces add [workspace] as a root-level coordinator.
hugo.toml / config.toml — Hugo static sites
Hugo prefers TOML for its config (YAML and JSON are also supported). Site-wide settings, menu definitions (arrays of tables — see lesson 7), taxonomy config, output formats — all in one TOML file at the project root.
Principle: when picking a config format for a new tool, look at what your audience already maintains. A Python developer touches pyproject.toml daily; a Rust dev touches Cargo.toml daily. Matching the muscle memory reduces friction. TOML's win in those ecosystems was as much about familiarity as syntax.
Code
pyproject.toml — minimal modern Python project·toml
[package]
name = "pippa-cli"
version = "0.1.0"
edition = "2021"
authors = ["C.W.K.", "Pippa"]
license = "MIT"
[dependencies]
clap = { version = "4", features = ["derive"] }
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
[dev-dependencies]
pretty_assertions = "1"
[[bin]]
name = "pippa"
path = "src/main.rs"
hugo.toml — static site config·toml
baseURL = "https://example.com"
languageCode = "en-us"
title = "My Hugo Site"
theme = "papermod"
[params]
author = "C.W.K."
description = "Where words live in markdown."
[[menu.main]]
name = "Posts"
url = "/posts/"
weight = 1
[[menu.main]]
name = "About"
url = "/about/"
weight = 2
Read pyproject.toml from Python·python
import tomllib
with open('pyproject.toml', 'rb') as f:
cfg = tomllib.load(f)
print(cfg['project']['name']) # 'pippa'
print(cfg['tool']['ruff']['line-length']) # 100
for dep in cfg['project']['dependencies']:
print(' -', dep)
Open the pyproject.toml of one of your projects (or pick a popular one — Pydantic, FastAPI, ruff). Identify all the [tool.*] sections. Pick one tool you don't currently use (mypy, ruff-isort, coverage) and read its docs to write a sensible [tool.<name>] block. The 'one config file for everything' workflow is what TOML enables.
Progress
Progress is local-only — sign in to sync across devices.