YAML Guide

What Is YAML? A Complete Guide to YAML Syntax and Usage

By S. Nitya·Published ·Updated ·14 min read

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.com

No 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: value

Key-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 comment

Document 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 Formatter

YAML 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: 0xFF

Booleans

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     # risky

Null

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 null

Dates

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 string

Multi-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: true

Sequences (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: 80

Flow 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: secret

YAML 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.

FeatureYAMLJSON
ReadabilityHuman-friendly, minimal syntaxMore verbose, bracket-heavy
CommentsSupported (#)Not supported
Data typesRich (dates, null ~, !!type tags)6 basic types
StringsBare, single, or double quotedDouble quotes required
Multi-line stringsLiteral (|) and folded (>) blocksEscaped \n only
Superset of JSONYes (since YAML 1.2)
Anchors & aliasesSupported (& and *)Not supported
Multiple documentsSupported (---)Not supported
Parsing speedSlower (complex spec)Faster
Best forConfig files, DevOps toolingWeb APIs, data storage

Same data, two formats

YAML — readable

# User config
name: Alice
age: 30
roles:
  - admin
  - editor

JSON — 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 Converter

Anchors 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_email

Anchors 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

LanguageLibraryParseSerialize
PythonPyYAMLyaml.safe_load()yaml.dump()
JavaScriptjs-yamlyaml.load()yaml.dump()
Gogo-yaml v3yaml.Unmarshal()yaml.Marshal()
RubyPsych (stdlib)YAML.load()obj.to_yaml
JavaSnakeYAMLyaml.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 Compare

YAML 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 build

YAML Best Practices

  1. 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.
  2. 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.
  3. Use explicit booleans (true/false). Never rely on yes/no or on/off as booleans. These were YAML 1.1 features that YAML 1.2 dropped. Different parsers handle them differently, causing subtle bugs.
  4. 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.
  5. Use safe_load in Python. Always use yaml.safe_load() (not yaml.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.

Error: Tabs instead of spaces

✗ Invalid

name: Alice
	age: 30
	active: true

✓ Fixed

name: Alice
  age: 30
  active: true
YAML strictly forbids tab characters for indentation. Configure your editor to insert spaces on Tab keypress.
Error: Missing space after colon

✗ Invalid

host:localhost
port:5432

✓ Fixed

host: localhost
port: 5432
A colon followed immediately by a non-space character is treated as part of a plain string, not a key separator.
Error: Unquoted colon in string value

✗ Invalid

title: Error: file not found

✓ Fixed

title: "Error: file not found"
Strings containing : # [ ] { } & * must be quoted (single or double) to avoid ambiguity.
Error: YAML 1.1 boolean surprise

✗ Invalid

enabled: yes
verbose: on
check: off

✓ Fixed

enabled: true
verbose: true
check: false
YAML 1.1 treated yes/no/on/off as booleans. YAML 1.2 does not — always use true/false for clarity.

Frequently 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.