JSON, YAML or TOML? Choosing a Text Format for Configuration Files
Almost every application needs configuration: ports, file paths, feature flags, credentials references. Three text formats dominate: JSON, YAML and TOML. All three can represent nested data, but they make different trade-offs between strictness, readability and features. Choosing the right one makes configuration easier to write and harder to get wrong.
The same settings in three formats
JSON:
{
"server": { "host": "0.0.0.0", "port": 8080 },
"features": ["search", "export"],
"debug": false
}
YAML:
server:
host: 0.0.0.0
port: 8080
features:
- search
- export
debug: false
TOML:
debug = false
features = ["search", "export"]
[server]
host = "0.0.0.0"
port = 8080
JSON: strict and universal
JSON is supported by virtually every language and is the standard for APIs. Its grammar is small and strict: strings use double quotes, keys must be strings, and trailing commas are not allowed. That strictness makes JSON predictable and easy to generate by programs.
For hand-edited configuration, JSON has drawbacks. Standard JSON has no comments, which makes it hard to explain settings, and the punctuation is easy to get wrong. Variants such as JSONC and JSON5 add comments and relaxed syntax, but only tools that support them can read those files.
YAML: readable and powerful
YAML uses indentation instead of braces, supports comments with # and is popular for infrastructure and CI configuration. It also supports multi-line strings, anchors for reusing blocks and multiple documents in one file.
YAML's flexibility creates pitfalls:
- Indentation is significant, and tabs are not allowed for indentation.
- Unquoted values are typed implicitly. Under YAML 1.1 rules, still used by some parsers, values like
no,yes,onandoffmay become booleans, so a country codeNOcan turn intofalse. - Values such as version numbers (
1.10) may be read as floats and lose the trailing zero. - Some loaders can construct arbitrary objects from tags, so untrusted YAML should be parsed with a safe loader.
Quoting strings that could be ambiguous avoids most of these surprises.
TOML: designed for configuration
TOML aims to be obvious to read and to map unambiguously to a hash table. It supports comments, has explicit types for strings, integers, floats, booleans and dates, and uses [section] headers similar to INI files. Strings must be quoted, which removes YAML's implicit typing problems.
TOML is used by several language ecosystems for project files, such as Rust's Cargo.toml and Python's pyproject.toml. Deeply nested structures can become verbose, since each nested table needs its own header or inline table syntax.
Comparison
| Feature | JSON | YAML | TOML |
|---|---|---|---|
| Comments | No (standard) | Yes | Yes |
| Implicit typing surprises | Few | Several | Few |
| Deep nesting | Good | Good | Verbose |
| Best for | Machine-generated data, APIs | Readable nested configs, CI/infra | Hand-edited app and project config |
Other options worth knowing
INI files remain common in older software and are fine for flat key-value settings, although there is no single INI standard. Environment variables suit a small number of deployment-specific values and are a common way to inject secrets into containers. Some tools accept configuration written in a programming language, which allows logic and reuse but makes the configuration harder to validate and to read for non-developers. For most applications, one declarative file plus environment overrides is a simple, robust combination.
Practical advice
- Follow the convention of your ecosystem or tool; consistency beats preference.
- Validate configuration at startup, ideally against a schema, and fail with a clear message.
- Keep secrets out of configuration files committed to version control; reference environment variables or a secret store instead.
- Quote ambiguous YAML values and avoid relying on implicit types.
Key takeaways
- JSON is strict and universal but lacks comments.
- YAML is readable and flexible but has typing and indentation pitfalls.
- TOML is explicit and comment-friendly, well suited to hand-edited configuration.