YAML was born in 2001 as an alternative to XML and JSON for configuration files. Its philosophy: maximize human readability without sacrificing expressiveness. A typical YAML file looks like pseudocode rather than a data format.
Key characteristics:
- Significant indentation: spaces (never tabs) define hierarchy. Two spaces is convention, some use four.
- No braces or brackets: unlike JSON, structure is inferred from indentation.
- Native comments:
# comment, something JSON doesn't support. - Rich data types: strings, numbers, booleans, null, arrays, objects, timestamps, even internal references (
&anchor,*alias).
Basic example:
app:\n name: Genfy\n port: 3000\n features:\n - auth\n - api\n - cms
JSON equivalent: {"app": {"name": "Genfy", "port": 3000, "features": ["auth", "api", "cms"]}}.
YAML is a superset of JSON: all valid JSON is valid YAML, but not vice versa. This allows gradual migration from JSON to YAML.
Scalars: simple values. Strings don't need quotes unless they contain special characters (:, #, @). Multiline with | (preserves breaks) or > (folds into one line).
description: |\n First line.\n Second line.\nsummary: >\n This folds\n into one line.
Lists: - item or JSON notation [item1, item2]. Can nest:
frameworks:\n - name: React\n type: frontend\n - name: Node\n type: backend
Dictionaries: key-value pairs. Keys with spaces require quotes: "My Key": value.
Anchors and aliases: avoid repetition. &default defines an anchor, *default references it:
defaults: &defaults\n timeout: 30\n retries: 3\napi:\n <<: *defaults\n endpoint: /v1
Explicit types: !!str, !!int, !!bool. Useful when parser infers wrong: version: !!str 1.0 (without it, parses as float).
Popular parsers: PyYAML (Python), js-yaml (JavaScript), go-yaml (Go). All support YAML 1.2, the current spec.
CI/CD: GitHub Actions, GitLab CI, CircleCI, Travis CI use YAML to define pipelines. Readability is critical when teams edit workflows frequently.
name: Deploy\non: [push]\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v3\n - run: npm install
Infrastructure as code: Kubernetes manifests, Docker Compose, Ansible playbooks, Terraform (HCL is similar). YAML describes desired system state.
Application configuration: frameworks like Symfony, Rails and Spring Boot use YAML for config (config.yml). More expressive than .env, less verbose than JSON.
Don't use for:
- APIs: JSON is standard and more efficient for automatic parsing.
- Large data: YAML is slow for gigabytes of data. Prefer JSON, CSV or binary formats (Parquet, Avro).
- When indentation is risky: one extra/missing space breaks the entire file. In teams without linters, JSON with explicit braces is safer.
Use YAML if:
- Humans edit the file frequently (configs, CI/CD).
- You need comments (JSON doesn't have them).
- You want to reduce visual noise (no braces/brackets).
- File has complex structure with anchors/aliases for DRY.
Use JSON if:
- It's for APIs or data exchange between systems.
- Parse performance matters (JSON is 3-10x faster).
- Team isn't familiar with strict indentation.
- You need validation with JSON Schema (more mature than YAML Schema).
Common YAML mistakes:
- Tabs: YAML rejects tabs. Configure your editor to convert tabs to spaces.
- Strings that look like booleans:
country: NOparses asfalse(NO is legacy Norwegian boolean). Use quotes:country: "NO". - Inconsistent indentation: mixing 2 and 4 spaces. Use a linter (yamllint) in pre-commit.
Tools: yq (like jq but for YAML), VS Code with YAML extension (autocomplete + validation), Genfy offers online YAML ↔ JSON converters.
Examples
# App config\napp:\n name: MyApp\n version: 1.0.0\n features:\n - auth\n - payments# Docker Compose\nservices:\n web:\n image: nginx\n ports:\n - "80:80"# GitHub Action\nname: CI\non: [push]\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: npm test# Anchors and aliases\ndefaults: &base\n timeout: 30\napi:\n <<: *base\n url: /v1# Multiline\ndescription: |\n First line\n Second line
FAQ
Does YAML support comments?
Yes. Comments start with # and go to end of line. This is a key advantage over JSON, which doesn't support native comments (only workarounds like special keys).
Can I use tabs in YAML?
No. YAML explicitly rejects tabs. Only spaces. Reason: tabs have ambiguous width (2, 4, 8 spaces depending on editor), breaking significant indentation. Configure your editor to convert tabs to spaces.
Is YAML slower than JSON?
Yes. Parsing YAML is 3-10x slower than JSON because it has more complex syntax (anchors, multiline, implicit types). For small config files it doesn't matter; for APIs with thousands of requests/second, JSON is preferable.