Snappy ToolsYAML (YAML Ain't Markup Language) is the configuration format behind Docker Compose, Kubernetes,...
YAML (YAML Ain't Markup Language) is the configuration format behind Docker Compose, Kubernetes, GitHub Actions, Ansible, and most CI/CD pipelines. It's readable, but it has sharp edges. Here's what you need to know.
YAML uses indentation (spaces only — never tabs) to represent structure:
name: Alice
age: 30
active: true
score: 9.5
nothing: null
These map directly to JSON types: strings, numbers, booleans, null.
Strings don't need quotes — unless they contain special characters:
# These are all strings without quotes
name: Alice
message: Hello, world
path: /usr/local/bin
# Use quotes when the value would otherwise be misinterpreted
version: "1.0" # Without quotes: parsed as float 1.0, not string
flag: "true" # Without quotes: parsed as boolean true
colon: "key: value" # Without quotes: YAML parser error
empty: "" # Explicit empty string
Single quotes (') prevent escape sequences. Double quotes (") allow them:
literal: 'Line\nbreak' # stored as: Line\nbreak (backslash-n literal)
escaped: "Line\nbreak" # stored as: Line + newline + break
# Literal block (|): preserves newlines
description: |
This is the first line.
This is the second line.
Newlines are preserved.
# Folded block (>): newlines become spaces
summary: >
This is a long description
that wraps across lines.
Output is one paragraph.
The | block is useful for scripts, SQL queries, or any content where line breaks matter. The > block is useful for long prose that should be treated as a single string.
# Block sequence
fruits:
- apple
- banana
- cherry
# Inline sequence
fruits: [apple, banana, cherry]
# Block mapping
address:
street: 123 Main St
city: London
postcode: SW1A 1AA
# Inline mapping
address: {street: 123 Main St, city: London}
users:
- name: Alice
role: admin
permissions:
- read
- write
- delete
- name: Bob
role: viewer
permissions:
- read
YAML is a superset of JSON — every valid JSON document is valid YAML. YAML adds:
#)To convert between the two formats, the YAML to JSON Converter handles both directions and validates syntax.
Different YAML parsers have different rules for implicit booleans. YAML 1.1 (used by many older parsers) treats these as booleans:
# YAML 1.1 — these are all booleans:
yes, no, on, off, true, false, y, n
country: NO # parsed as boolean false!
toggle: on # parsed as boolean true
YAML 1.2 (the current spec) only recognizes true and false as booleans. But many tools (PyYAML, Ruby's Psych) still use YAML 1.1 by default.
Fix: always quote values that look like booleans but aren't:
country: "NO"
toggle: "on"
port: 8080 # integer
ratio: 0.5 # float
hex: 0xFF # integer 255 (YAML 1.1)
octal: 0755 # integer 493 — dangerous! Looks like a permissions string
Version numbers and semver tags are particularly dangerous:
version: 1.10 # parsed as float 1.1 — not the string "1.10"!
version: "1.10" # correct: preserved as string
YAML is whitespace-sensitive. Two spaces per level is conventional, but consistency within a file matters more than the number:
# Wrong: inconsistent indentation
servers:
- name: web
port: 80
- name: db # Error: this dash is at a different indent level
port: 5432
# Right
servers:
- name: web
port: 80
- name: db
port: 5432
Tabs are never valid in YAML for indentation. Most YAML errors are either tabs or inconsistent indent depth.
YAML lets you define a value once and reuse it:
defaults: &defaults
timeout: 30
retries: 3
development:
<<: *defaults # merge all defaults
host: localhost
production:
<<: *defaults # merge again
host: prod.example.com
timeout: 60 # override one value
This is especially useful in Docker Compose for sharing service configuration and in CI/CD pipelines for shared job configuration.
GitHub Actions:
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
Docker Compose:
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
Kubernetes deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
template:
spec:
containers:
- name: app
image: myapp:latest
ports:
- containerPort: 8080
| Factor | YAML | JSON |
|---|---|---|
| Comments | Yes | No |
| Human writing | Easier | Verbose |
| Machine generation | Error-prone | Safer |
| Browser/JS native | Needs library | Native (JSON.parse) |
| Config files | Yes | Possible |
| API responses | Avoid | Preferred |
Use YAML for files humans edit (CI configs, Kubernetes manifests, application config). Use JSON for data exchange between programs.
YAML's strength is readability for humans writing configuration files. Its weakness is the implicit type coercion — things that look like strings silently become booleans or numbers. When in doubt, quote your strings, especially for version numbers, port numbers, country codes, and any value that overlaps with YAML's boolean keywords.