Kubernetes uses YAML. CloudFormation uses both JSON and YAML. Docker Compose uses YAML. GitHub Actions uses YAML. CI/CD pipelines use YAML. Meanwhile, APIs speak JSON, JavaScript objects are JSON-like, and package.json is, well, JSON. As a developer, you constantly shift between these two serialization formats.
They represent the same data structures but with different syntax philosophies: JSON uses braces and brackets with explicit delimiters; YAML uses indentation with minimal syntax.
The same data in both formats
JSON:
{
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {
"name": "web-app",
"labels": {
"app": "web"
}
},
"spec": {
"replicas": 3,
"template": {
"spec": {
"containers": [
{
"name": "web",
"image": "nginx:1.24",
"ports": [{"containerPort": 80}]
}
]
}
}
}
}
YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web
spec:
replicas: 3
template:
spec:
containers:
- name: web
image: nginx:1.24
ports:
- containerPort: 80
The YAML version is more compact and arguably more readable. No braces, no brackets, no commas, no quotes around most strings. But the reliance on indentation means that a single misaligned space can change the meaning or break the document entirely.
YAML features JSON lacks
Comments. YAML supports comments with #. This alone is why many configuration formats chose YAML over JSON.
# This is the production configuration
replicas: 3 # Scale up during peak hours
Multi-line strings. YAML has multiple ways to handle long strings:
# Literal block (preserves newlines)
description: |
This is a long description
that spans multiple lines.
# Folded block (joins lines with spaces)
description: >
This is a long description
that gets folded into one line.
Anchors and aliases. YAML can reference repeated values:
defaults: &defaults
timeout: 30
retries: 3
production:
<<: *defaults
timeout: 60
YAML gotchas
Norway problem. In YAML 1.1, NO is parsed as boolean false. This broke country code lists: {country: NO} became {country: false}. YAML 1.2 fixed this, but many parsers still use 1.1 behavior.
Indentation sensitivity. Two spaces vs four spaces both work, but mixing them is an error. And a tab character in YAML is always an error.
Implicit typing. version: 1.0 becomes a float, not a string. version: "1.0" is a string. If your Docker Compose version or API version is parsed as a number, things break quietly.
# This is the number 1.0, not the string "1.0"
version: 1.0
# This is the string "1.0"
version: "1.0"
Quoted strings. Most strings do not need quotes in YAML. But strings starting with special characters (*, &, !, %, @) or containing : followed by a space do need quotes.
Converting in code
// JSON to YAML (using js-yaml library)
const yaml = require('js-yaml');
const jsonObj = JSON.parse(jsonString);
const yamlString = yaml.dump(jsonObj, { lineWidth: -1 });
// YAML to JSON
const yamlObj = yaml.load(yamlString);
const jsonString = JSON.stringify(yamlObj, null, 2);
import json
import yaml
# JSON to YAML
json_obj = json.loads(json_string)
yaml_string = yaml.dump(json_obj, default_flow_style=False)
# YAML to JSON
yaml_obj = yaml.safe_load(yaml_string)
json_string = json.dumps(yaml_obj, indent=2)
Note: always use yaml.safe_load() in Python, not yaml.load(). The unsafe version can execute arbitrary Python code from specially crafted YAML.
I built a JSON/YAML converter at zovo.one/free-tools/json-yaml-converter that converts between the two formats instantly. Paste JSON, get YAML. Paste YAML, get JSON. It handles all the edge cases -- comments (preserved in YAML), multi-line strings, and proper type handling. Essential for working across the JSON/YAML divide in modern DevOps and development workflows.
I'm Michael Lip. I build free developer tools at zovo.one. 500+ tools, all private, all free.
Top comments (0)