What Is YAML? A Complete Guide to YAML Syntax and Usage
Open any Kubernetes manifest, Docker Compose file, or GitHub Actions workflow and you will see YAML. It has become the universal language of DevOps configuration — chosen specifically because it is readable by both humans and machines. This guide explains what YAML is, how its syntax works, where it trips developers up, and how to use it effectively across languages and tools.
What Is YAML?
YAML (“YAML Ain't Markup Language”) is a human-readable data serialisation language. It is designed to represent structured data — lists, dictionaries, strings, numbers — in a format that is easy to write by hand and easy to read without special tooling.
Unlike JSON, which uses curly braces and square brackets to denote structure, YAML uses indentation. The nesting of keys communicates hierarchy, the same way Python code uses indentation to show block structure.
Here is a simple YAML document representing a server configuration:
---
# Server configuration
server:
host: api.example.com
port: 8080
tls: true
database:
host: db.example.com
name: myapp
pool_size: 10
features:
dark_mode: true
beta_users:
- alice@example.com
- bob@example.comNo brackets, no quotes needed for most values, full support for comments. This is why DevOps tooling adopted YAML so broadly: configuration files are written and reviewed by humans far more often than they are parsed by machines.
A Brief History of YAML
YAML was first proposed by Clark Evans in 2001, with contributions from Ingy döt Net and Oren Ben-Kiki. The original name was “Yet Another Markup Language” — a playful nod to the proliferation of markup languages at the time. The name was changed to the recursive acronym “YAML Ain't Markup Language” to emphasise that it is a data format, not a document format.
Key version milestones:
- YAML 1.0 (January 2004) — first stable specification. Introduced the core syntax: indentation-based structure, block/flow styles, anchors, and aliases.
- YAML 1.1 (January 2005) — added sexagesimal (base-60) numbers, expanded boolean literals (
yes/no,on/off), and various improvements. - YAML 1.2 (2009) — the landmark revision. Made YAML a strict superset of JSON, removed problematic implicit type coercions from 1.1, and removed sexagesimal numbers. Most modern tooling targets 1.2.
- YAML 1.2.2 (October 2021) — current version. Clarified edge cases, added errata, and improved the formal grammar. Available at yaml.org.
YAML gained mainstream adoption with the rise of DevOps tooling: Ruby on Rails config files (2004–2008), Ansible playbooks (2012), Docker Compose (2014), and Kubernetes manifests (2014– present) all standardised on YAML. Today it is the dominant configuration language for cloud-native infrastructure.
YAML Syntax Fundamentals
Indentation
YAML uses spaces (never tabs) to express hierarchy. The number of spaces per level is flexible, but must be consistent within a block. Two spaces per level is the most common convention.
# Correct — 2-space indentation
parent:
child:
grandchild: value
# Also correct — 4-space indentation
parent:
child:
grandchild: valueKey-Value Pairs
A mapping key and value are separated by a colon followed by a space: key: value. The space is mandatory — key:value (no space) is treated as a plain string, not a key-value pair.
Comments
A # character (with a preceding space, or at the start of a line) begins a comment that runs to the end of the line. Inline comments after values are allowed.
# Full-line comment
server: localhost # inline comment
port: 8080 # another inline commentDocument Markers
A YAML file can contain multiple documents separated by --- (document start marker). An optional ... marks the document end. Most tools produce single-document files, but Kubernetes kubectl apply -f frequently concatenates multiple manifests with ---.
---
# Document 1
name: alice
---
# Document 2
name: bob
...Validate and format your YAML instantly
Paste any YAML into the free YAML Formatter — it highlights indentation errors, validates syntax, and formats the document, entirely in your browser.
Open YAML FormatterYAML Data Types
YAML has a rich type system with automatic (implicit) type detection. Understanding how parsers infer types prevents unexpected behaviour.
Strings
Strings can be bare (unquoted), single-quoted, or double-quoted. Use quotes when the value contains special characters or could be misinterpreted as another type.
# All three are strings
bare: Hello World
single: 'Can''t stop, won''t stop' # '' escapes single quote inside
double: "Line one\nLine two" #
is a newline escape
# These need quoting to stay strings
version: "1.0" # without quotes, parsed as float 1.0
enabled: "true" # without quotes, parsed as boolean
empty: "" # quoted empty string (vs null)Numbers
integer: 42
negative: -7
float: 3.14159
scientific: 6.022e23
octal: 0o17 # YAML 1.2 octal notation
hex: 0xFFBooleans
In YAML 1.2, only true and false (lowercase) are booleans. In YAML 1.1, the values yes, no, on, and off were also treated as booleans — this is a common source of bugs when upgrading parsers.
# YAML 1.2 — always use these
active: true
debug: false
# YAML 1.1 booleans (avoid — may be parsed as strings in strict 1.2 parsers)
enabled: yes # risky
verbose: on # riskyNull
Null is represented as null, ~, or an empty value (just the key with nothing after the colon).
deleted_at: null
alias: ~
unset: # empty value — also nullDates
YAML 1.1 parsers automatically convert ISO 8601 date strings to native date objects. YAML 1.2 treats them as strings. Quote dates if you need them as strings in 1.1 environments.
created: 2026-05-23
timestamp: 2026-05-23T10:00:00.000Z
safe_date: "2026-05-23" # always a stringMulti-Line Strings
YAML provides two block scalar styles for multi-line text — one of its most powerful features.
# Literal block (|) — preserves all newlines
script: |
echo "Step 1: install"
npm install
echo "Step 2: test"
npm test
# Folded block (>) — newlines become spaces (except blank lines)
description: >
This is a very long description
that wraps across several lines
but renders as a single paragraph.
A blank line starts a new paragraph.Mappings and Sequences
YAML's two collection types — mappings (dictionaries) and sequences (lists) — can be written in either block style (using indentation) or flow style (using JSON-like brackets).
Mappings (Block Style)
user:
id: usr_001
name: Alice Smith
email: alice@example.com
active: trueSequences (Block Style)
# Sequence of scalars
roles:
- admin
- editor
- viewer
# Sequence of mappings (list of objects)
servers:
- host: web1.example.com
port: 80
- host: web2.example.com
port: 80Flow Style (JSON-Like)
Flow style uses brackets and braces, identical to JSON syntax. Useful for short inline collections where block style would be unnecessarily verbose.
# Flow sequence
tags: [admin, beta, power-user]
# Flow mapping
coordinates: {lat: 51.5, lng: -0.12}
# Mixed — block outer, flow inner
servers:
- {host: web1.example.com, port: 80}
- {host: web2.example.com, port: 80}Nested Collections
config:
server:
host: localhost
port: 8080
tls:
enabled: true
cert: /etc/ssl/cert.pem
key: /etc/ssl/key.pem
database:
host: db.example.com
credentials:
username: app_user
password: secretYAML vs JSON
Since YAML 1.2, every valid JSON document is valid YAML — YAML is a strict superset of JSON. In practice, they serve different purposes and shine in different contexts.
| Feature | YAML | JSON |
|---|---|---|
| Readability | Human-friendly, minimal syntax | More verbose, bracket-heavy |
| Comments | Supported (#) | Not supported |
| Data types | Rich (dates, null ~, !!type tags) | 6 basic types |
| Strings | Bare, single, or double quoted | Double quotes required |
| Multi-line strings | Literal (|) and folded (>) blocks | Escaped \n only |
| Superset of JSON | Yes (since YAML 1.2) | — |
| Anchors & aliases | Supported (& and *) | Not supported |
| Multiple documents | Supported (---) | Not supported |
| Parsing speed | Slower (complex spec) | Faster |
| Best for | Config files, DevOps tooling | Web APIs, data storage |
Same data, two formats
YAML — readable
# User config
name: Alice
age: 30
roles:
- admin
- editorJSON — explicit
{
"name": "Alice",
"age": 30,
"roles": [
"admin",
"editor"
]
}Bottom line: Use YAML for configuration files that humans write and review — infrastructure manifests, CI/CD pipelines, application settings. Use JSON for web APIs, inter-service communication, and data storage where parsing speed and strict types matter. For a complete JSON reference, see our What Is JSON guide.
Convert YAML to JSON (or JSON to YAML)
Need to bridge the two formats? The free YAML to JSON Converter handles it instantly, in your browser.
Open YAML to JSON ConverterAnchors and Aliases
Anchors and aliases let you define a value once and reuse it — the YAML equivalent of a variable. This keeps configuration DRY (Don't Repeat Yourself) and prevents divergence when the same values appear in multiple places.
&name— defines an anchor at this node*name— inserts an alias (copy) of the anchored value<<: *name— merge key: merges all keys from the anchored mapping into the current mapping
# Define default settings once
defaults: &defaults
timeout: 30
retries: 3
log_level: info
region: us-east-1
# Reuse and selectively override
production:
<<: *defaults # inherit all defaults
host: prod.example.com
timeout: 60 # override just this value
staging:
<<: *defaults
host: staging.example.com
log_level: debug # more verbose logging in staging
# Simple scalar anchor
admin_email: &admin admin@example.com
contact: *admin # same value as admin_emailAnchors and aliases are evaluated by the YAML parser before the document is returned to your application — the consuming code sees fully resolved values with no special handling required. Note that YAML 1.2 explicitly forbids circular references in anchors.
Parsing YAML
Unlike JSON (which has native browser support), YAML requires a library in every environment. Here are the most common parsers.
Python (PyYAML)
PyYAML is the de-facto Python YAML library. Always use yaml.safe_load() instead of yaml.load() — the latter allows arbitrary Python object instantiation and is a security risk with untrusted input.
import yaml
# Parse YAML string → Python dict
yaml_str = """
name: Alice
roles:
- admin
- editor
active: true
"""
data = yaml.safe_load(yaml_str)
print(data['name']) # Alice
print(data['roles']) # ['admin', 'editor']
# Serialise Python dict → YAML string
output = yaml.dump(
{'name': 'Bob', 'active': True, 'score': 98.5},
default_flow_style=False,
sort_keys=False,
)
# name: Bob
# active: true
# score: 98.5
# Read from file
with open('config.yaml') as f:
config = yaml.safe_load(f)
# Write to file
with open('output.yaml', 'w') as f:
yaml.dump(config, f, default_flow_style=False)JavaScript (js-yaml)
js-yaml is the most popular JavaScript YAML library (used internally by webpack, ESLint, Jest, and many other tools).
import yaml from 'js-yaml'; // npm install js-yaml
// Parse YAML string → JavaScript object
const data = yaml.load(yamlString);
console.log(data.name); // Alice
console.log(data.roles); // ['admin', 'editor']
// Stringify JavaScript object → YAML string
const output = yaml.dump({ name: 'Bob', active: true, score: 98.5 });
// Node.js: read/write files
import fs from 'node:fs';
const config = yaml.load(fs.readFileSync('config.yaml', 'utf8'));
fs.writeFileSync('output.yaml', yaml.dump(config));Other Languages — Quick Reference
| Language | Library | Parse | Serialize |
|---|---|---|---|
| Python | PyYAML | yaml.safe_load() | yaml.dump() |
| JavaScript | js-yaml | yaml.load() | yaml.dump() |
| Go | go-yaml v3 | yaml.Unmarshal() | yaml.Marshal() |
| Ruby | Psych (stdlib) | YAML.load() | obj.to_yaml |
| Java | SnakeYAML | yaml.load() | yaml.dump() |
Compare two YAML files
Spot every addition, removal, and change between two YAML files with the free YAML Compare tool — side-by-side diff with deep structural analysis.
Open YAML CompareYAML in DevOps
YAML's readability made it the default configuration format for the modern DevOps ecosystem. Here are the three most common real-world contexts you will encounter.
Docker Compose
Docker Compose uses YAML to define multi-container applications: services, volumes, networks, and environment variables.
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db
restart: unless-stopped
db:
image: postgres:15
environment:
POSTGRES_DB: myapp
POSTGRES_USER: app_user
POSTGRES_PASSWORD: secret
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:Kubernetes Deployment
Kubernetes manifests are YAML documents describing the desired state of cluster resources. A Deployment manages replicated pod instances.
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:1.0.0
ports:
- containerPort: 8080
env:
- name: NODE_ENV
value: production
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"GitHub Actions
GitHub Actions workflows are YAML files in .github/workflows/ that define CI/CD pipelines triggered by repository events.
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build
run: npm run buildYAML Best Practices
- Configure your editor for YAML. Set your editor to insert spaces on the Tab key (never real tabs), use 2-space indentation, and trim trailing whitespace. Most editors have YAML-specific extensions that highlight indentation errors in real time.
- Quote strings that look like other types. Values that look like numbers, booleans, dates, or null but should be strings must be quoted:
"1.0","true","2026-05-23","null". When in doubt, quote it. - Use explicit booleans (true/false). Never rely on
yes/nooron/offas booleans. These were YAML 1.1 features that YAML 1.2 dropped. Different parsers handle them differently, causing subtle bugs. - Use anchors to eliminate repetition. When the same block of configuration appears in multiple places (e.g., default environment variables across deployment stages), extract it into an anchor (
&name) and merge it with<<: *name. This prevents divergence and reduces maintenance burden. - Use safe_load in Python. Always use
yaml.safe_load()(notyaml.load()) when parsing YAML from untrusted sources. The unsafe variant can deserialise arbitrary Python objects and is a remote code execution vector.
Common YAML Errors
These four mistakes account for the majority of YAML parse failures in the wild.
✗ Invalid
name: Alice
age: 30
active: true✓ Fixed
name: Alice
age: 30
active: true✗ Invalid
host:localhost
port:5432✓ Fixed
host: localhost
port: 5432✗ Invalid
title: Error: file not found✓ Fixed
title: "Error: file not found"✗ Invalid
enabled: yes
verbose: on
check: off✓ Fixed
enabled: true
verbose: true
check: falseFrequently Asked Questions
- What does YAML stand for?
- YAML stands for "YAML Ain't Markup Language" — a recursive acronym chosen to emphasise that YAML is a data serialisation format, not a document markup language like XML or HTML. It was originally called "Yet Another Markup Language" when first proposed in 2001, but the name was revised to clarify its purpose.
- Is YAML a superset of JSON?
- Yes — since YAML 1.2 (published in 2009), every valid JSON document is also valid YAML. The YAML 1.2 specification was deliberately aligned with JSON to make it easy to migrate between the two formats. You can parse a JSON file with a YAML parser and get the expected result.
- What is the difference between YAML and JSON?
- YAML is designed for human readability: it uses indentation instead of brackets, supports comments with #, allows bare (unquoted) strings, and provides features like multi-line blocks, anchors, and aliases that JSON lacks. JSON is stricter, faster to parse, and universally supported in browser APIs. Use YAML for config files and DevOps tooling; use JSON for web APIs and data exchange.
- Why does YAML use indentation instead of brackets?
- YAML's designers prioritised human readability over machine convenience. Indentation mirrors how people naturally structure information — the same reason Python uses it. The trade-off is that indentation errors (especially mixing tabs and spaces) are a common source of bugs. Always configure your editor to insert spaces for tabs in YAML files.
- How do I validate YAML online for free?
- Use the free YAML Formatter at jsonbuddy.net/yaml-formatter. Paste your YAML and the tool instantly highlights syntax errors, validates structure, and formats the document with correct indentation — all in your browser without sending data to any server.
Ready to work with YAML?
JSON Buddy gives you free browser-based tools for YAML — format, validate, compare, and convert YAML to JSON or XML. No signup. Your data never leaves your browser.