YAML File Documentation


Summary

A .yaml (or .yml) file is a YAML document: human-readable structured data written in YAML (“YAML Ain’t Markup Language”), used heavily for app config, CI/CD pipelines, Docker Compose and Kubernetes. It is plain UTF‑8 text with the MIME type application/yaml, so any code editor opens it — VS Code or Notepad++ on Windows, TextEdit on Mac, vim on Linux. YAML is indentation-sensitive and forbids tabs, so use a whitespace-aware editor. Since YAML 1.2, every JSON file is also valid YAML.

Technical details

FeatureValue
Full nameYAML Ain’t Markup Language
File extension.yaml (also .yml)
MIME typeapplication/yaml
Format typeHuman-readable data-serialization text
AuthorsClark Evans, Ingy döt Net, Oren Ben-Kiki
CategoryDeveloper / config file
Introduced2001 (YAML 1.0)
Current specYAML 1.2 (2009; revised 1.2.2 in 2021)
Open standardYes — public specification
EncodingUTF‑8 (UTF‑16 / UTF‑32 also permitted)
IndentationSpaces only — tabs are illegal
Comments# to end of line (JSON has none)
Magic numberNone — plain text; optional --- document start
Relation to JSONSince YAML 1.2, JSON is a strict subset of YAML
Common usesDocker Compose, Kubernetes, GitHub Actions, Ansible, site config
Related extensions.yml, .json, .toml, .ini, .xml, .env
Specificationyaml.org/spec/1.2.2/
Syntax at a glance

YAML is plain UTF‑8 text with no file signature. A mapping is written key: value (note the space after the colon); a sequence is a list of - item lines. Structure comes from indentation with spaces — tabs are forbidden and cause a parse error. Comments start with #. Optional --- marks a document start and ... a document end, letting one file hold several documents. Block scalars | (keep newlines) and > (fold lines) carry multi-line strings, and &anchor / *alias reuse a value. Since YAML 1.2 any valid JSON is also valid YAML.

What is a yaml file?

A .yaml file (also written .yml) is a document written in YAML, a recursive acronym for “YAML Ain’t Markup Language”. YAML is a human-friendly data-serialization language first released in 2001, with the current YAML 1.2 specification dating from 2009 and revised as 1.2.2 in 2021. It represents the same kinds of data as JSON — mappings of key to value, sequences (lists), and scalars such as strings, numbers, booleans and null — but with a layout designed to be easy for people to read and write, using indentation instead of braces and dashes instead of array brackets.

YAML became the default configuration language of modern DevOps and cloud tooling. You find it as docker-compose.yml, as Kubernetes manifests, as GitHub Actions, GitLab CI and CircleCI pipeline files, as Ansible playbooks, and as the config of countless applications and static-site generators. A common misconception is that YAML is tied to Python; it is not. YAML is language-independent and is used across Go, Java, JavaScript and more, and its strong association with cloud tooling comes from that ecosystem, not from any one language.

Mappings, sequences and scalars

Every YAML document is built from three node kinds. A mapping is a set of key: value pairs, where the space after the colon is required. A sequence is a list, each entry on its own line beginning with a dash and a space. A scalar is a single value: a string, number, boolean or null. These nest freely, and the nesting is expressed by indentation rather than punctuation.

server:
  host: example.com      # a mapping nested under "server"
  port: 8080
  tags:                  # a sequence
    - web
    - production
  enabled: true          # a boolean scalar
  notes: null            # a null scalar

The same data in JSON needs braces, brackets, quoted keys and commas; YAML replaces all of that with layout. Strings usually need no quotes, though you can single- or double-quote them when a value would otherwise be ambiguous. YAML also supports comments with # to the end of a line, a feature JSON lacks, which is one reason YAML is preferred for hand-edited configuration.

Significant whitespace: spaces, never tabs

YAML’s defining rule, and its most common pitfall, is that structure is defined by indentation and that indentation must use spaces. Tabs are forbidden and produce a parse error, because a tab’s width is ambiguous and would make nesting undefined. The number of spaces is not fixed by the spec, but every level must be indented more than its parent and siblings must align exactly; a single misaligned line silently changes which parent a key belongs to, or triggers an error. This is why a YAML-aware editor that shows whitespace and converts tabs to spaces is strongly recommended over a plain editor like Notepad, which hides the very characters that matter.

Scalar surprises: the Norway problem and bare numbers

Because unquoted scalars are interpreted by type, YAML has a family of gotchas where a value means something other than the literal text. The best known is the “Norway problem”: under the older YAML 1.1 rules, the unquoted words no, yes, on and off are read as booleans, so a country list containing NO (Norway) parses NO as false. Similarly, an unquoted value that looks like a number or a date is parsed as that type, so a version string 1.20 becomes the number 1.2, and a ZIP code with a leading zero can lose it or be read as octal.

country: NO        # parsed as false under YAML 1.1 rules!
version: 1.20      # parsed as the number 1.2
zip: 01234         # may be read as a number, losing the leading zero
# fix by quoting:
country: "NO"
version: "1.20"
zip: "01234"

The remedy is to quote any scalar whose literal text matters. YAML 1.2 tightened the core boolean rules, but many parsers still follow 1.1 behaviour, so quoting remains the safe habit for strings that could be mistaken for another type.

Block scalars and anchors

Two features handle repetition and multi-line text. Block scalars carry strings that span several lines: the literal style, introduced with |, preserves newlines exactly, while the folded style, introduced with >, joins wrapped lines into spaces. These are how a shell script or a certificate is embedded in a config file without escaping every newline.

script: |
  echo "line one"
  echo "line two"     # newlines kept verbatim

defaults: &db          # anchor names this block
  adapter: postgres
  pool: 5

production:
  <<: *db              # merge/alias reuses the anchored block
  host: db.internal

An anchor, written &name, labels a node so it can be referenced later with an alias *name, letting you define a block once and reuse it without repetition. The merge key << combined with an alias pulls one mapping’s keys into another, a common way to share defaults across environments.

Multi-document files and the JSON relationship

A single .yaml file can hold more than one document, separated by a --- line that marks a document start; an optional ... marks a document end. Kubernetes manifests use this heavily, packing several resources into one file. As of YAML 1.2, JSON is a strict subset of YAML: any valid JSON file is also valid YAML, which is why the flow style {key: value, list: [1, 2]} works inside YAML too. Converting YAML to JSON is therefore essentially lossless in principle, with the one exception that comments are dropped, since JSON has none. Tools like yq (yq -o=json file.yaml) and editor commands do this conversion.

Frequently asked questions

What is the difference between .yaml and .yml?

None — they are the same YAML format with two extensions. .yml is the older three-letter form. Use whichever the tool expects; you can simply rename the file.

Why is my YAML giving an indentation or parse error?

YAML uses spaces for structure and forbids tabs, so a stray tab or a misaligned line breaks it. Open the file in a YAML-aware editor that shows whitespace and converts tabs to spaces, or paste it into an online validator to find the exact line.

How do I convert YAML to JSON?

Use yq -o=json file.yaml, a VS Code command, or an online converter. It is essentially lossless since JSON is a subset of YAML; only comments are dropped.

Is YAML only for Python?

No, that is a common misconception. YAML is language-independent and is used everywhere: Docker Compose, Kubernetes, GitHub Actions, Ansible, and apps written in Go, Java and JavaScript. Python simply has a popular YAML library (PyYAML).

References