14 min read

YAML Syntax: Complete Guide with Examples for Developers

Everything you need to know about YAML syntax, data types, nested structures, anchors, multi-line strings, and real-world configuration files for Docker Compose, GitHub Actions, and Kubernetes.

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

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.

When to Use Anchors

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.

Open NexTool YAML Editor

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.

Open YAML to JSON Converter

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 Editor

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

NexTool Team

We build free, privacy-first developer tools. Our mission is to make the tools you reach for every day faster, cleaner, and more respectful of your data.