TOML vs YAML: Same Config, Three Formats

TOML is an INI-like format built for config files: explicit [table] headers, quoted strings, real date types and no meaningful indentation. YAML relies on indentation, guesses types from bare values and adds anchors and multiple documents. For shallow settings TOML is harder to break; for deep nesting YAML reads better.

TOML, YAML and JSON at a glance
TOML 1.0YAML 1.2JSON
Nesting[table] and [a.b] headersIndentationBraces
Comments# to end of line# to end of lineNone
StringsAlways quotedQuotes optionalAlways double-quoted
Dates and timesBuilt-in typesNot in the 1.2 core schemaStrings only
Case-sensitiveYesYesYes
Media typeapplication/tomlapplication/yamlapplication/json

Updated

Most of the time you do not get to choose: Python packaging reads pyproject.toml, Rust reads Cargo.toml, and GitHub Actions and Docker Compose read YAML. When you do choose, seeing one config in all three formats makes the trade-offs obvious. Pick a sample below and compare.

One config in TOML, YAML and JSON

Pick a sample. All three versions hold exactly the same data, so you can compare how each format spells it out.

TOML

# Shop settings
title = "Harbour Bakery"
debug = false
opens = 07:30:00

[database]
host = "db.internal"
port = 5432

[email]
from = "[email protected]"
retries = 3

YAML

# Shop settings
title: Harbour Bakery
debug: false
opens: "07:30:00"

database:
  host: db.internal
  port: 5432

email:
  from: [email protected]
  retries: 3

JSON

{
  "title": "Harbour Bakery",
  "debug": false,
  "opens": "07:30:00",
  "database": { "host": "db.internal", "port": 5432 },
  "email": { "from": "[email protected]", "retries": 3 }
}

In the app settings sample, TOML stores opens as a real local time, while the YAML and JSON versions keep it as a string.

Which files use which format

Common config files and the format they require
FileFormatRead by
pyproject.tomlTOMLPython build tools and packaging
Cargo.tomlTOMLCargo, the Rust package manager
.github/workflows/*.ymlYAMLGitHub Actions
compose.yamlYAMLDocker Compose
package.jsonJSONnpm and other Node package managers
Markdown front matterYAML (TOML with +++ in Hugo)Static site generators

TOML syntax worth knowing

Dotted keys, inline tables and dates

Dotted keys and inline tables avoid extra headers for small groups, and dates are typed values, not strings.

site.name = "Harbour Bakery"
site.url = "https://harbour.example"
owner = { name = "Ana", email = "[email protected]" }
launched = 2026-11-02
updated = 2026-11-02T09:15:00Z
notes = """
Closed on public holidays.
Orders after 4pm ship next day."""

Where each format is required

Python projects describe themselves in pyproject.toml and Rust crates in Cargo.toml, so TOML is the norm in those ecosystems. Hugo also accepts TOML front matter between +++ lines.

CI pipelines, container setups and deployment manifests lean on YAML: GitHub Actions workflows and Docker Compose files are both YAML, and the extension you choose is mostly about consistency.

What TOML gives up for safety

TOML's goal, in its own spec, is to map unambiguously to a hash table. That means no guessing: text needs quotes, booleans are only true and false, and every table is named in a header.

The price is repetition in nested data. Three levels deep, a TOML file repeats the table path in every header, while YAML just indents.

How it works

  1. Choose one of the sample configs: app settings, a package manifest or a list of servers.
  2. Read the same data in TOML, YAML and JSON next to each other.
  3. Notice where TOML needs headers ([[servers]]) and where YAML needs careful indentation.
  4. Copy whichever version your tool expects.

Tips

Frequently asked questions

Is TOML better than YAML?

Neither wins everywhere. TOML's explicit headers and mandatory quotes make small and medium config files hard to misread. YAML handles deep nesting and long lists with less noise, at the price of whitespace-sensitive syntax and implicit typing.

Why does Python use pyproject.toml?

The Python packaging guides define pyproject.toml with three tables: [build-system] for the build backend, [project] for metadata such as name, version and dependencies, and [tool] for settings of individual tools like linters.

Can TOML represent everything YAML can?

Not everything. TOML has no anchors or aliases, no multiple documents per file and no null, since every key must be given a value. For configuration that rarely matters, but YAML data that leans on those features will not convert one to one.

Which formats do Docker Compose and GitHub Actions accept?

Both use YAML. GitHub Actions workflows live in .github/workflows with a .yml or .yaml extension, and Compose looks for compose.yaml by default, still accepting docker-compose.yaml for older projects.

Does TOML support multi-line strings?

Yes. Three double quotes start a multi-line basic string that allows escapes, and three single quotes start a multi-line literal string that keeps its content exactly as written.

Related: YAML vs JSON, YAML comments, YAML to JSON converter, JSON formatter, pnpm vs npm.

Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.

More in Guides

We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.

Product

Who It's For

Features

Resources

Company

View Sitemap