X Xerobit

YAML Syntax Guide — Indentation, Types, and Common Patterns

YAML syntax uses indentation to define structure. Here's how YAML handles scalars, sequences, mappings, anchors, and multiline strings — with examples for every common pattern.

Mian Ali Khalid · · 6 min read
Use the tool
YAML ↔ JSON Converter
Convert between YAML and JSON formats with full fidelity.
Open YAML ↔ JSON Converter →

YAML (YAML Ain’t Markup Language) uses indentation and human-readable symbols to represent structured data. Unlike JSON’s explicit braces and brackets, YAML’s structure emerges from indentation — which makes it readable but also error-prone when indentation is inconsistent.

Use the YAML to JSON Converter to convert YAML to JSON and validate YAML syntax.

Basic structure

YAML has three fundamental data types: scalars, sequences, and mappings.

Scalars (strings, numbers, booleans)

# Strings (quotes optional for simple values):
name: Alice
title: "Hello, World"
description: 'It''s a test'  # Single quote escapes with double-single-quote

# Numbers:
age: 30
price: 9.99
hex_value: 0xff
scientific: 1.2e5

# Booleans:
active: true
enabled: false
debug: yes   # Also valid: yes/no, on/off, true/false

# Null:
middle_name: null
nickname: ~    # Also null

Gotcha — boolean strings: yes, no, on, off, true, false are parsed as booleans in YAML 1.1 (used by most parsers). Use quotes if you mean the string:

answer: "yes"   # String "yes"
answer: yes     # Boolean true in YAML 1.1!

Sequences (arrays)

# Block style (preferred for readability):
fruits:
  - apple
  - banana
  - cherry

# Flow style (compact, like JSON):
fruits: [apple, banana, cherry]

# Nested sequence:
matrix:
  - [1, 2, 3]
  - [4, 5, 6]
  - [7, 8, 9]

Mappings (objects/dicts)

# Block style:
user:
  name: Alice
  email: alice@example.com
  age: 30

# Flow style:
user: {name: Alice, email: alice@example.com, age: 30}

# Nested mapping:
database:
  primary:
    host: db1.example.com
    port: 5432
  replica:
    host: db2.example.com
    port: 5432

Multiline strings

YAML has two styles for multiline string values:

Literal block scalar (|) — preserves newlines

description: |
  This is the first line.
  This is the second line.
  Third line.

The value is:

This is the first line.\nThis is the second line.\nThird line.\n

Trailing newline is included. |- removes the final newline.

Folded block scalar (>) — folds newlines to spaces

description: >
  This is a long sentence that
  wraps across multiple lines
  but becomes a single line.

The value is:

This is a long sentence that wraps across multiple lines but becomes a single line.\n

Single newlines become spaces; blank lines become newlines (paragraph breaks).

Practical uses

# SQL query in config:
query: |
  SELECT users.id, users.name
  FROM users
  WHERE users.active = true
  ORDER BY users.created_at DESC

# Shell script:
startup_script: |
  #!/bin/bash
  export APP_ENV=production
  npm start

# Multiline description (keep as single paragraph):
summary: >
  This tool converts data between formats.
  It supports JSON, YAML, and CSV inputs.
  Output can be formatted or minified.

Anchors and aliases

Anchors (&) define a value you can reference later. Aliases (*) reference it:

# Define anchor:
defaults: &defaults
  timeout: 30
  retry: 3
  log_level: info

# Use alias (merge into mapping):
production:
  <<: *defaults      # Merge all defaults
  timeout: 60        # Override specific keys
  host: prod.example.com

development:
  <<: *defaults
  host: localhost
  log_level: debug

The <<: merge key is a YAML extension for merging mappings. Without it, *alias just copies the reference:

shared_config: &shared
  key1: value1
  key2: value2

service_a:
  config: *shared   # service_a.config = {key1: value1, key2: value2}

Complex keys and special characters

# Key with spaces (use quotes):
"full name": Alice Smith

# Key with special characters:
"content-type": application/json

# Numeric keys:
1: first
2: second

# Empty string key:
"": default value

Multiple documents in one file

YAML files can contain multiple documents separated by ---:

---
name: document1
type: config

---
name: document2
type: data
values: [1, 2, 3]

Kubernetes manifests use this to combine multiple resources in one YAML file.

YAML tags (explicit types)

Force a specific type when YAML’s automatic parsing isn’t what you want:

# Force string type:
port: !!str 8080          # "8080" not 8080
truth: !!str true         # "true" not boolean

# Force integer:
pi: !!float 3             # 3.0 not 3

# Force binary:
picture: !!binary |
  R0lGODlhDAAMAIQAAP//9tX...

# Force timestamp:
created: !!timestamp 2024-03-04

Common YAML errors

Tab indentation: YAML prohibits tabs. Only spaces allowed for indentation.

# WRONG (tab character):
parent:
	child: value  # Error!

# CORRECT (spaces):
parent:
  child: value

Inconsistent indentation:

# WRONG: items at different indentation levels
list:
  - item1
    - item2  # This is a child of item1, not list!

# CORRECT:
list:
  - item1
  - item2

Unquoted strings with special characters:

# WRONG:
url: https://example.com:8080/path  # Colon triggers YAML interpretation
message: Hello: World               # Colon after non-space triggers mapping

# CORRECT:
url: "https://example.com:8080/path"
message: "Hello: World"

Trailing spaces: Trailing spaces after a value can cause parsing issues in strict YAML parsers.

Parsing YAML in code

JavaScript

import yaml from 'js-yaml';

const yamlString = `
name: Alice
age: 30
hobbies:
  - reading
  - coding
`;

// Parse YAML to JavaScript object:
const data = yaml.load(yamlString);
console.log(data.name);         // "Alice"
console.log(data.hobbies[0]);   // "reading"

// Convert JS object to YAML:
const obj = { name: 'Bob', active: true, scores: [95, 87] };
const yamlOutput = yaml.dump(obj);
console.log(yamlOutput);
// "name: Bob\nactive: true\nscores:\n  - 95\n  - 87\n"

Python

import yaml

yaml_string = """
name: Alice
age: 30
hobbies:
  - reading
  - coding
"""

# Parse YAML:
data = yaml.safe_load(yaml_string)
print(data['name'])         # "Alice"
print(data['hobbies'][0])   # "reading"

# Use safe_load (not yaml.load) to prevent arbitrary code execution

# Dump to YAML:
obj = {'name': 'Bob', 'active': True, 'scores': [95, 87]}
print(yaml.dump(obj, default_flow_style=False))

Related posts

Related tool

YAML ↔ JSON Converter

Convert between YAML and JSON formats with full fidelity.

Written by Mian Ali Khalid. Part of the Data & Format pillar.