DEV Community

Snappy Tools
Snappy Tools

Posted on

YAML for Developers: Syntax, Gotchas, and When to Use It

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.

Basic syntax

YAML uses indentation (spaces only — never tabs) to represent structure:

name: Alice
age: 30
active: true
score: 9.5
nothing: null
Enter fullscreen mode Exit fullscreen mode

These map directly to JSON types: strings, numbers, booleans, null.

Strings

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Multiline strings

# 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.
Enter fullscreen mode Exit fullscreen mode

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.

Lists

# Block sequence
fruits:
  - apple
  - banana
  - cherry

# Inline sequence
fruits: [apple, banana, cherry]
Enter fullscreen mode Exit fullscreen mode

Objects / mappings

# Block mapping
address:
  street: 123 Main St
  city: London
  postcode: SW1A 1AA

# Inline mapping
address: {street: 123 Main St, city: London}
Enter fullscreen mode Exit fullscreen mode

Nested structures

users:
  - name: Alice
    role: admin
    permissions:
      - read
      - write
      - delete
  - name: Bob
    role: viewer
    permissions:
      - read
Enter fullscreen mode Exit fullscreen mode

YAML vs JSON

YAML is a superset of JSON — every valid JSON document is valid YAML. YAML adds:

  • Comments (#)
  • Multiline strings
  • No quotes required for strings
  • Anchors and aliases for reuse

To convert between the two formats, the YAML to JSON Converter handles both directions and validates syntax.

The Norway problem and other gotchas

Boolean parsing

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

Number parsing

port: 8080     # integer
ratio: 0.5     # float
hex: 0xFF      # integer 255 (YAML 1.1)
octal: 0755    # integer 493 — dangerous! Looks like a permissions string
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Indentation errors

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
Enter fullscreen mode Exit fullscreen mode

Tabs are never valid in YAML for indentation. Most YAML errors are either tabs or inconsistent indent depth.

Anchors and aliases

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
Enter fullscreen mode Exit fullscreen mode

This is especially useful in Docker Compose for sharing service configuration and in CI/CD pipelines for shared job configuration.

Common use cases

GitHub Actions:

name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test
Enter fullscreen mode Exit fullscreen mode

Docker Compose:

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

When to use YAML vs JSON

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.

Top comments (0)