DEV Community

Snappy Tools
Snappy Tools

Posted on

YAML vs JSON: When to Use Each and How to Convert Between Them

YAML and JSON both represent structured data, but they're optimized for different use cases. Here's when to use each and how to convert between them.

At a glance

JSON YAML
Syntax Strict, machine-friendly Flexible, human-friendly
Comments No Yes (# comment)
Quotes Required for strings Optional for most strings
Indentation Not significant Significant (structure)
Multi-line strings Awkward Clean (`
Primary use API responses, data interchange Configuration files
Supersets JSON is a subset of YAML

When to use JSON

API responses and requests: JSON is the standard. It's compact, fast to parse, and universally supported. Every language has built-in JSON parsing.

Data storage: When you're storing structured data that will be read by machines (database, message queues, event payloads), JSON's strictness is a feature — less ambiguity means fewer parsing edge cases.

Config files that are code-generated: If a tool writes the config file, JSON's strict format is easier to generate correctly.

When to use YAML

Configuration files humans will edit: YAML's lack of braces and quotes makes it dramatically more readable for humans. This is why Kubernetes manifests, GitHub Actions, Docker Compose, Ansible playbooks, and many other tools use YAML — these files are written and maintained by people.

When you need comments: JSON has no comment syntax. YAML comments ({% raw %}# this is a comment) are essential for documenting configuration options.

Multi-line strings: YAML has clean syntax for literal blocks (|) and folded strings (>):

description: |
  This is a multi-line string.
  Each line is preserved exactly.
  No escaping needed.

folded_description: >
  This is a folded string.
  These lines will be joined
  with spaces into one long line.
Enter fullscreen mode Exit fullscreen mode

The JSON equivalent requires \n escaping:

{
  "description": "This is a multi-line string.\nEach line is preserved exactly.\nNo escaping needed."
}
Enter fullscreen mode Exit fullscreen mode

YAML features that JSON lacks

Anchors and aliases (DRY config):

defaults: &defaults
  image: node:20-alpine
  timeout: 300

build:
  <<: *defaults
  command: npm run build

test:
  <<: *defaults
  command: npm test
  timeout: 600  # Override defaults
Enter fullscreen mode Exit fullscreen mode

This is impossible in JSON — repeated configuration must be duplicated.

Multiple documents in one file:

---
kind: Deployment
metadata:
  name: my-app
---
kind: Service
metadata:
  name: my-app-service
Enter fullscreen mode Exit fullscreen mode

Used extensively in Kubernetes to deploy multiple resources from a single file.

YAML boolean traps:

YAML 1.1 (the version many tools use) parses certain strings as booleans:

# These are booleans in YAML 1.1, NOT strings:
enabled: yes   # true
disabled: no   # false
active: on     # true
inactive: off  # false
Enter fullscreen mode Exit fullscreen mode

This is a common source of bugs in YAML config. If you mean the string "yes" or "no", quote it:

country: "no"    # Norway's country code — NOT a boolean
answer: "yes"    # The word "yes" — NOT a boolean
Enter fullscreen mode Exit fullscreen mode

YAML 1.2 (2009+) removed most of these ambiguities, but tool support varies.

Converting between formats

For one-off conversions: A YAML ↔ JSON converter handles the conversion in the browser without any setup.

Python:

import yaml, json

# JSON to YAML
json_str = '{"name": "Alice", "active": true}'
data = json.loads(json_str)
yaml_str = yaml.dump(data, default_flow_style=False)

# YAML to JSON
yaml_str = "name: Alice\nactive: true\n"
data = yaml.safe_load(yaml_str)
json_str = json.dumps(data, indent=2)

# File conversion
with open('config.yaml') as f:
    data = yaml.safe_load(f)
with open('config.json', 'w') as f:
    json.dump(data, f, indent=2)
Enter fullscreen mode Exit fullscreen mode

JavaScript/Node.js:

const yaml = require('js-yaml');
const fs = require('fs');

// YAML to JSON
const yamlContent = fs.readFileSync('config.yaml', 'utf8');
const data = yaml.load(yamlContent);
const jsonContent = JSON.stringify(data, null, 2);

// JSON to YAML
const jsonContent2 = fs.readFileSync('config.json', 'utf8');
const data2 = JSON.parse(jsonContent2);
const yamlContent2 = yaml.dump(data2);
Enter fullscreen mode Exit fullscreen mode

Command line:

# Python (no dependencies)
python3 -c "import sys, json, yaml; print(json.dumps(yaml.safe_load(sys.stdin), indent=2))" < config.yaml

# Or pipe:
cat config.yaml | python3 -c "import sys, json, yaml; print(json.dumps(yaml.safe_load(sys.stdin), indent=2))"

# yq (the jq for YAML — install: pip install yq or brew install yq)
yq -j '.' config.yaml      # YAML to JSON
cat data.json | yq -y '.'   # JSON to YAML
Enter fullscreen mode Exit fullscreen mode

YAML pitfalls for developers

Tabs are not allowed for indentation. YAML specifically forbids tabs. If you paste YAML from a source that uses tabs, the parser will error.

Indentation creates structure. Unlike JSON, YAML's structure is defined entirely by indentation. Misalign a key by one space and the structure changes silently.

The Norway problem:

country_codes:
  - no   # Parses as false (boolean) in YAML 1.1!
  - gb
  - us
Enter fullscreen mode Exit fullscreen mode

Use quotes: - "no"

Numbers can surprise you:

version: 1.0   # float, not "1.0" string
port: 8080     # integer
hex: 0x1F      # integer (31) — if you wanted the string "0x1F", quote it
Enter fullscreen mode Exit fullscreen mode

Practical YAML validation:

Run yamllint before committing config files:

pip install yamllint
yamllint kubernetes/
Enter fullscreen mode Exit fullscreen mode

It catches tab characters, missing blank lines before lists, and other style issues that cause silent parsing problems.


Use JSON for APIs and machine-to-machine data. Use YAML for human-maintained config files where readability and comments matter. When converting between them, be aware of YAML's boolean and number auto-conversion quirks — those are the most common source of conversion bugs.

Top comments (0)