What Is YAML and Why Developers Use It
YAML (YAML Ain't Markup Language) is a human-readable data serialization format. It was designed from the ground up to be easy to read, easy to write by hand, and expressive enough to represent complex data structures. If you have ever written a docker-compose.yml, a GitHub Actions workflow, or a Kubernetes manifest, you have already written YAML.
The format was created in 2001 by Clark Evans, Ingy dot Net, and Oren Ben-Kiki. The current specification is YAML 1.2 (released in 2009), which formally defines YAML as a superset of JSON. That means every valid JSON document is also valid YAML, but YAML offers additional features that JSON does not: comments, multi-line strings, anchors for reuse, and indentation-based nesting that eliminates the visual noise of braces and brackets.
Today, YAML is the dominant configuration format in the DevOps ecosystem. Docker Compose, Kubernetes, Ansible, GitHub Actions, GitLab CI, CircleCI, Terraform (HCL aside), Helm charts, and dozens of other tools use YAML as their primary configuration language. Understanding YAML syntax is not optional for modern developers -- it is a daily requirement.
This guide covers every aspect of YAML syntax you need to write, read, and debug configuration files confidently. Every example is valid YAML that you can paste into the NexTool YAML Editor to validate and experiment with.
YAML Basics: Structure and Indentation
YAML uses whitespace indentation to represent structure. There are no curly braces, no square brackets (in the standard block style), and no semicolons. The visual layout of the file is the structure.
Key-Value Pairs (Mappings)
The most fundamental YAML construct is a key-value pair. A key and its value are separated by a colon followed by a space.
name: Alice
age: 30
email: alice@example.com
The space after the colon is mandatory. Writing name:Alice without the space is a syntax error. This single rule trips up more beginners than any other YAML feature.
Indentation Rules
YAML uses spaces for indentation. Tabs are not allowed. The YAML specification explicitly forbids tab characters for indentation. Most YAML files use 2-space indentation, though any consistent number of spaces works. What matters is that sibling elements use the same indentation level.
server:
host: localhost
port: 8080
ssl:
enabled: true
certificate: /path/to/cert.pem
In this example, host, port, and ssl are all children of server (indented 2 spaces). The keys enabled and certificate are children of ssl (indented 4 spaces total, 2 relative to their parent).
Comments
YAML supports single-line comments with the # character. Comments can appear on their own line or at the end of a line after a value. There is no multi-line comment syntax.
# This is a full-line comment
name: Alice # This is an inline comment
# age: 30 # This line is commented out
Comments are one of the biggest advantages of YAML over JSON. You can document why a configuration value exists, not just what it is.
Documents
A single YAML file can contain multiple documents, separated by ---. A document can optionally end with .... This is commonly used in Kubernetes manifests where a single file defines multiple resources.
---
apiVersion: v1
kind: Service
metadata:
name: web
---
apiVersion: v1
kind: Deployment
metadata:
name: web
Spaces only, never tabs. Use 2-space indentation. Always put a space after colons. These three rules will prevent 90% of YAML syntax errors.
YAML Data Types
YAML automatically infers data types from values. You do not need to declare types explicitly, but understanding how YAML interprets your values is critical to avoiding bugs.
Strings
Most values in YAML are strings, and most strings do not need quotes. YAML treats unquoted values as strings when they do not match any other type pattern.
# All of these are strings
name: Alice
city: New York
path: /usr/local/bin
# Quote strings that contain special characters
message: "Hello: World" # Colon would cause parsing issues
regex: '[a-z]+' # Square brackets would start a flow sequence
special: "true" # Without quotes, this would be a boolean
version: "1.0" # Without quotes, this would be a float
Use double quotes when you need escape sequences (\n, \t, \\). Use single quotes when you want the value treated as a literal string with no escape processing. Use no quotes when the value is unambiguous.
Numbers
YAML recognizes integers, floats, and special numeric values.
# Integers
count: 42
negative: -17
hex: 0xFF
octal: 0o77
# Floats
price: 19.99
scientific: 1.5e+10
# Special values
infinity: .inf
negative_infinity: -.inf
not_a_number: .nan
Booleans
YAML 1.2 recognizes true and false (case-insensitive) as boolean values. Older YAML 1.1 parsers also accept yes, no, on, off, which is a notorious source of bugs. The string "Norway" with country code NO has been accidentally parsed as a boolean false in YAML 1.1 parsers.
# Booleans
active: true
debug: false
# DANGER: these may be interpreted as booleans in YAML 1.1
# Always quote them if you mean strings
country_code: "NO" # Quote to prevent boolean interpretation
answer: "yes" # Quote to keep as string
Null
Null values can be represented with null, ~, or by leaving the value empty.
explicit_null: null
tilde_null: ~
empty_null:
Lists (Sequences)
Lists use a dash followed by a space (- ) for each item. Items are indented under their parent key.
fruits:
- apple
- banana
- cherry
# Inline (flow) syntax
colors: [red, green, blue]
Dictionaries (Mappings)
Dictionaries are the key-value structures you have already seen. They can also be written in inline (flow) syntax.
# Block syntax
person:
name: Alice
age: 30
# Inline (flow) syntax
person: {name: Alice, age: 30}
Nested Structures: Lists of Objects and Complex Data
The real power of YAML becomes apparent when you combine mappings and sequences to represent complex, deeply nested data. This is where most configuration files live.
List of Objects
The most common pattern in DevOps configurations is a list of objects -- for example, a list of services, a list of environment variables, or a list of deployment steps.
employees:
- name: Alice
role: engineer
skills:
- Python
- Kubernetes
- Terraform
- name: Bob
role: designer
skills:
- Figma
- CSS
- SVG
Each - starts a new list item. The keys under each dash (name, role, skills) are properties of that item. The skills key itself contains a nested list.
Deeply Nested Structures
There is no limit to nesting depth. Here is a three-level structure that represents a server configuration.
infrastructure:
production:
servers:
- hostname: web-01
region: us-east-1
resources:
cpu: 4
memory: 16GB
storage:
type: ssd
size: 500GB
- hostname: web-02
region: eu-west-1
resources:
cpu: 8
memory: 32GB
storage:
type: ssd
size: 1TB
When structures get this deep, consistent indentation is everything. Use the NexTool YAML Editor to validate complex files as you write them, catching indentation errors before they become deployment failures.
Multi-Line Strings
YAML has sophisticated support for multi-line string values, which is one of its strongest advantages over JSON. There are two block scalar styles: literal and folded.
Literal Block Scalar ( | )
The pipe character preserves all line breaks exactly as written. Each newline in the YAML source becomes a newline in the string value.
script: |
#!/bin/bash
echo "Starting deployment"
docker build -t myapp .
docker push myapp:latest
echo "Done"
The resulting string contains five lines with a trailing newline. This is ideal for embedding shell scripts, SQL queries, or any content where line breaks are significant.
Folded Block Scalar ( > )
The greater-than character folds newlines into spaces, producing a single long line. Blank lines are preserved as actual newlines.
description: >
This is a long description
that spans multiple lines
in the YAML source but will
be folded into a single
paragraph when parsed.
This starts a new paragraph
because of the blank line above.
The first five lines become one paragraph. The blank line creates a line break, and the last two lines become a second paragraph.
Chomping Indicators
You can control trailing newlines with chomping indicators appended to the block scalar style.
# Default (clip): single trailing newline
default: |
text here
# Strip (-): no trailing newline
stripped: |-
text here
# Keep (+): preserve all trailing newlines
kept: |+
text here
The strip indicator (-) is the most commonly used in practice. When embedding scripts or configuration snippets, you usually do not want a trailing newline.
Anchors and Aliases: Reuse Without Repetition
YAML anchors let you define a value once and reference it multiple times. This eliminates duplication in configuration files and ensures that shared values stay in sync when you change them.
Basic Anchors
Define an anchor with & and reference it with *.
defaults: &default_settings
timeout: 30
retries: 3
log_level: info
development:
<<: *default_settings
log_level: debug
production:
<<: *default_settings
timeout: 60
The &default_settings anchor marks the defaults mapping. The <<: *default_settings syntax merges all keys from the anchor into the current mapping. Keys defined after the merge override the anchored values, so development gets log_level: debug instead of info, and production gets timeout: 60 instead of 30.
Anchoring Individual Values
Anchors work on any value, not just mappings.
database_host: &db_host "db.production.internal"
services:
api:
database: *db_host
worker:
database: *db_host
analytics:
database: *db_host
If the database hostname changes, you update it in one place. All three services automatically use the new value.
Use anchors when the same configuration block appears in multiple places. Common use cases include shared database settings, default environment variables, and base container configurations in Docker Compose files. If you find yourself copying and pasting YAML blocks, replace them with anchors.
Real-World YAML Examples
Theory is useful. Seeing how YAML is used in actual tools is better. Here are three configurations you are likely to write or read in any modern development workflow.
Docker Compose
version: "3.9"
services:
web:
build: .
ports:
- "8080:80"
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://db:5432/app
depends_on:
- db
- redis
restart: unless-stopped
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_DB: app
POSTGRES_USER: admin
POSTGRES_PASSWORD: ${DB_PASSWORD}
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
pgdata:
This file defines three services (web, db, redis), their relationships (depends_on), environment variables, port mappings, and a named volume. Notice the use of both list syntax (- "8080:80") and mapping syntax (POSTGRES_DB: app) for environment variables -- Docker Compose accepts both.
GitHub Actions
name: CI Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build
run: npm run build
This workflow runs on push and pull request events to the main branch. It uses a matrix strategy to test against three Node.js versions in parallel. Each step in the steps list is an object with either uses (for pre-built actions) or run (for shell commands).
Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: myapp:1.2.0
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 10
periodSeconds: 30
Kubernetes manifests are among the most deeply nested YAML files you will encounter. This deployment defines a pod template with resource limits, health checks, and replica count. Getting the indentation wrong here means your deployment fails. Validate complex Kubernetes YAML with a dedicated YAML validator before applying it to a cluster.
YAML vs JSON vs TOML: Choosing the Right Format
YAML, JSON, and TOML are the three most common data serialization formats for configuration and data exchange. Each has strengths that make it the right choice in specific contexts.
| Feature | YAML | JSON | TOML |
|---|---|---|---|
| Comments | Yes | No | Yes |
| Multi-line strings | Yes (|, >) | No | Yes (""") |
| Anchors / reuse | Yes | No | No |
| Readability | Excellent | Good | Excellent |
| Deep nesting | Clean | Verbose | Awkward |
| Parsing speed | Slower | Fastest | Fast |
| Data interchange | Uncommon | Standard | Uncommon |
| Whitespace-sensitive | Yes | No | No |
Choose YAML when you need a human-edited configuration file with comments and complex nested data. Docker Compose, Kubernetes, CI/CD pipelines -- YAML is the established standard here.
Choose JSON when machines are the primary consumers. API responses, data interchange between services, and package.json are all good fits. JSON is also the safest choice when the data must be parsed across many different languages and environments without ambiguity. You can quickly convert between the two formats using the NexTool YAML to JSON Converter.
Choose TOML when your configuration is relatively flat and you want a format that is unambiguous and easy to parse. TOML is the standard for Rust (Cargo.toml), Python (pyproject.toml), and Hugo. It struggles with deeply nested data, which is where YAML and JSON are better options.
Common YAML Mistakes and How to Avoid Them
YAML is forgiving in some ways and ruthless in others. These are the errors that cause the most frustration.
1. Tabs Instead of Spaces
This is the number-one YAML error. YAML forbids tabs for indentation. Period. Configure your editor to convert tabs to spaces. Enable the "show whitespace" setting so you can see the difference visually.
2. Missing Space After Colon
key:value is not a valid key-value pair. YAML requires key: value with a space. Some parsers will silently interpret the entire string as a key with a null value, which creates subtle bugs that are hard to track down.
3. Unquoted Special Values
Values like yes, no, true, false, null, on, off, and strings that look like numbers or timestamps will be auto-converted to their typed equivalents. If you mean a string, quote it.
# Bug: country code "NO" becomes boolean false
country: NO
# Fix: quote the value
country: "NO"
# Bug: version 1.0 becomes float
version: 1.0
# Fix: quote to keep as string
version: "1.0"
4. Inconsistent Indentation
Mixing 2-space and 4-space indentation within the same parent-child relationship will break your YAML. Pick one convention and stick with it throughout the file.
5. Colons in Unquoted Strings
A colon followed by a space triggers key-value parsing. If your string contains : , wrap it in quotes.
# Bug: parser sees "Note" as a key
message: Note: this will fail
# Fix: quote the entire value
message: "Note: this will fail"
Tools for Working with YAML
The right tooling eliminates the friction of writing and debugging YAML. Here are the tools we recommend, all free and running entirely in your browser.
NexTool YAML Editor
A browser-based YAML editor with real-time validation, syntax highlighting, and instant error feedback. Write or paste YAML, and see errors highlighted as you type. No data leaves your browser.
NexTool YAML to JSON Converter
Convert YAML to JSON and back with a single click. Useful when you need to transform a YAML configuration into JSON for an API, or when you want to validate your YAML by viewing the equivalent JSON structure.
NexTool JSON to YAML Converter
Starting with a JSON configuration and need YAML? The JSON to YAML converter produces clean, properly indented YAML from any valid JSON input. Particularly helpful when migrating configurations from JSON-based tools to YAML-based ones.
NexTool YAML Formatter
Reformat messy or inconsistently indented YAML into clean, standardized output. The YAML formatter normalizes indentation, fixes spacing, and validates your document in a single pass.
Validate Your YAML Right Now
No sign-up, no ads, no data leaving your browser. Paste your YAML and get instant validation with line-level error messages.
Open NexTool YAML EditorFrequently Asked Questions
What is YAML and what does it stand for?
YAML stands for "YAML Ain't Markup Language" (a recursive acronym). It is a human-readable data serialization format commonly used for configuration files. Unlike JSON, YAML uses indentation instead of braces to represent structure, supports comments, and is designed to be easy to read and write by hand. It is the standard configuration format for Docker Compose, Kubernetes, GitHub Actions, Ansible, and many other DevOps tools.
What is the difference between YAML and JSON?
YAML and JSON can represent the same data structures, but they differ in syntax and use cases. YAML uses indentation for nesting and supports comments, multi-line strings, and anchors. JSON uses braces and brackets, does not support comments, and is stricter but easier to parse programmatically. YAML is preferred for configuration files that humans read and edit. JSON is preferred for data interchange between APIs and applications. Every valid JSON document is also valid YAML, but the reverse is not true. You can convert between them instantly with the NexTool YAML/JSON converter.
Why does my YAML file have a parsing error?
The most common YAML parsing errors are caused by inconsistent indentation (mixing tabs and spaces), missing spaces after colons in key-value pairs, incorrect quoting of special characters, and improper nesting of lists and maps. YAML requires spaces for indentation, not tabs. Every colon in a key-value pair must be followed by at least one space. Paste your YAML into a validator like NexTool YAML Editor to see the exact line and nature of the error.
How do I convert YAML to JSON or JSON to YAML?
You can convert between YAML and JSON using browser-based tools like the NexTool YAML to JSON Converter, which processes everything client-side. In Python, use PyYAML: import yaml, json, then call yaml.safe_load() to parse YAML and json.dumps() to output JSON. In Node.js, the js-yaml package provides yaml.load() and yaml.dump(). Since YAML is a superset of JSON, any JSON document can be used directly as YAML without conversion.
Can I use tabs for indentation in YAML?
No. The YAML specification explicitly forbids tab characters for indentation. You must use spaces. Most YAML files use 2-space indentation, though any consistent number of spaces is valid. This is the single most common source of YAML parsing errors for beginners. Configure your editor to insert spaces when you press the Tab key, and enable the "show whitespace" option to catch mixed indentation before it causes problems.
Explore 150+ Free Developer Tools
YAML Editor is just the start. NexTool has free tools for JSON, regex, CSV, colors, encoding, hashing, and much more.
Browse All Free Tools