YAML is a human-readable data serialization format that represents nested mappings, sequences and scalar values through indentation and minimal punctuation. Among data formats, it occupies the niche of files that people write and review by hand, above all configuration files, deployment manifests and CI pipeline definitions, while machines read the same file without loss of structure.
The current specification is YAML 1.2, first published in 2009 and revised in 2021. Version 1.2 was designed so that every valid JSON document is also valid YAML, which makes YAML a superset of JSON in practice, with extra features such as comments, anchors and multi-document streams.
How YAML represents data
YAML represents data with three building blocks: mappings of keys to values, sequences of ordered items, and scalars such as strings, numbers, booleans and null. Nesting is expressed by indentation with spaces; tab characters are not allowed for indentation, and every level must be indented consistently.
The same structure can be written in block style, with one entry per line, or in flow style, which uses JSON-like braces and brackets. Block style dominates in configuration because it produces clean diffs in version control.
| Element | Syntax | Meaning |
|---|---|---|
| Mapping | key: value | Key-value pair; nested by indentation |
| Sequence | - item | List entry at the current indentation |
| Comment | # text | Ignored by parsers |
| Document marker | --- | Starts a new document in one stream |
| Anchor and alias | &name and *name | Defines and reuses a node |
| Block scalar | | or > | Multi-line text, literal or folded |
| Tag | !!str, !!int | Explicit type of a node |
Anchors and aliases turn a YAML document from a tree into a graph: a node defined once can be referenced many times. Many tools also support the merge key << to copy mapping entries, although it was never part of the YAML 1.2 core.
Implicit typing and its pitfalls
YAML infers the type of unquoted scalars through implicit typing, and this convenience is the format’s most notorious source of errors. The result depends on the schema and version the parser implements, and many widely used libraries still follow YAML 1.1 rules.
| Written value | YAML 1.1 parsers | YAML 1.2 core schema | Safe form |
|---|---|---|---|
NO, yes, on | Boolean | String | Quote the value |
010 | Octal number 8 | Integer 10 | Quote if it is a code |
1.10 | Float 1.1 | Float 1.1 | Quote version strings |
22:30 | Sexagesimal number 1350 | String | Quote times |
null, ~, empty | Null | Null | Quote if text is meant |
The classic case is a country list in which the code for Norway, NO, becomes boolean false. The reliable rule is to quote every string that could look like another type, especially codes, versions, times and identifiers with leading zeros.
Multi-line text and multi-document streams
YAML handles long text better than most data formats through block scalars. A literal block keeps every line break exactly as written, which suits embedded scripts, certificates and SQL statements. A folded block joins lines into one paragraph and keeps only blank lines as breaks, which suits long descriptions that should wrap in the editor but not in the output.
Both styles accept chomping indicators that control the final line break: one keeps trailing newlines, one strips them, and the default keeps a single newline. These details look minor, yet a missing or extra newline at the end of a script or key file is a frequent cause of failed deployments that are hard to diagnose.
A single YAML file can also contain several documents separated by three dashes. Container orchestration tools use this to keep related resources, such as a service and its deployment, in one file while each document is still parsed and applied as an independent unit. Tools that expect exactly one document may silently read only the first, so the number of documents in a stream should be part of validation.
YAML compared with other data formats
YAML trades parsing simplicity for human readability. Other formats in the same family make the opposite trade or target different data shapes.
| Format | Strength | Weakness | Typical use |
|---|---|---|---|
| YAML | Readable, comments, references | Complex specification, implicit typing | Configuration, manifests |
| JSON | Simple, strict, universal parsers | No comments, verbose for humans | APIs, data interchange |
| XML | Schemas, namespaces, mixed content | Verbose, heavy tooling | Documents, enterprise exchange |
| CSV | Compact tabular rows | No nesting, weak typing | Spreadsheets, bulk exports |
| Parquet | Columnar, compressed, typed | Not human-readable | Analytics storage |
| NDJSON | One record per line, streamable | No comments, JSON only | Logs, event streams |
YAML is a poor choice for large datasets or high-throughput interchange: parsers are slower than JSON parsers, and indentation-based files are fragile when generated by templates. It is a strong choice when files are edited by people and versioned alongside code.
Using YAML safely in practice
Safe YAML use rests on restricting what the parser may do and validating structure before the data is used. Several precautions are standard practice.
- Load untrusted input only with a safe loader that builds plain maps, lists and scalars; full loaders in some languages can instantiate arbitrary objects and execute code.
- Limit alias expansion, because nested aliases enable billion laughs style memory exhaustion.
- Validate documents against a schema, for example a JSON Schema applied to the parsed data.
- Run a linter in continuous integration to catch indentation, duplicate keys and trailing spaces.
- Prefer two-space indentation and block style for consistent diffs.
Duplicate keys deserve special attention: the specification forbids them, yet many parsers silently keep the last value. A linter or strict parser mode turns this silent override into a visible error.
Understanding it simply
YAML is a way of writing structured information so that people can read it as easily as computers. It looks like a tidy outline. Each setting sits on its own line, and indentation shows what belongs under what.
Because it is so relaxed, YAML sometimes guesses wrong. A short word such as no can be read as yes-or-no instead of text. Putting such values in quotation marks removes the guesswork.
Applied in practice
A platform team keeps the deployment settings of about 40 services in YAML manifests stored next to the source code. Each manifest lists the container image, resource limits, environment variables and health checks. Anchors define shared settings once, and pull requests show every change as a readable line diff.
After an incident in which an unquoted version 1.10 was deployed as 1.1, the team adds a linter and a schema check to the pipeline and requires quoted version strings. The next similar mistake is rejected in review before deployment, and configuration-related rollbacks become rare. The manifests remain the single reviewed source of deployment configuration.