jsonyamlconfiguration

JSON vs YAML: When to Use Each Format

· Cosyslabs

JSON is the right choice for APIs, data interchange, and machine-generated configuration. YAML is better for human-authored configuration files where comments, readability, and minimal punctuation matter. YAML is a superset of JSON — every valid JSON document is valid YAML, but YAML has significant pitfalls you must know before adopting it.

Syntax Comparison

// JSON
{
  "server": {
    "host": "localhost",
    "port": 8080,
    "tls": true
  },
  "database": {
    "url": "postgres://localhost/mydb",
    "pool": {
      "min": 2,
      "max": 10
    }
  },
  "features": ["auth", "api", "admin"]
}
# YAML — same data, more readable
server:
  host: localhost
  port: 8080
  tls: true

database:
  url: postgres://localhost/mydb
  pool:
    min: 2
    max: 10

features:
  - auth
  - api
  - admin

YAML removes quotes, braces, brackets, and commas. It uses indentation (spaces only — no tabs) to convey structure.

YAML Is a Superset of JSON

You can embed JSON directly in a YAML file and it is valid:

# This is valid YAML
name: Alice
config: {"debug": true, "level": 3}

This means YAML parsers can parse JSON, and YAML-to-JSON converters are lossless (except for YAML-specific features like anchors and comments, which JSON cannot represent).

Where JSON Wins

API Responses

JSON is the lingua franca of REST APIs. Every HTTP client, from curl to browser fetch, handles JSON natively:

const response = await fetch("/api/users");
const data = await response.json(); // Built-in JSON parsing

YAML has no native browser support and adds a parser dependency (~15 KB for js-yaml).

Strict Type Handling

JSON has explicit types: string, number, boolean, null, array, object. YAML infers types from values, which causes notorious bugs.

Machine-Generated Data

Programs generating configuration or data should emit JSON. JSON is unambiguous, widely supported, and does not depend on whitespace.

JavaScript Ecosystem

package.json, tsconfig.json, eslintrc.json — JavaScript tooling standardized on JSON. Editors provide JSON Schema validation with autocomplete and error detection.

Where YAML Wins

Human-Authored Configuration

# YAML allows comments — JSON does not
# This comment explains why the timeout is high
server:
  timeout: 30000  # milliseconds — legacy clients need extra time

# Multi-line strings are readable in YAML
message: |
  Welcome to the system.
  Your account has been created.
  Please check your email to verify.

JSON's package.json has no comment support — developers work around this with // keys or external tools. YAML's comments enable inline documentation.

Kubernetes, GitHub Actions, Docker Compose

The cloud-native ecosystem standardized on YAML for manifests and pipelines:

# GitHub Actions workflow
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test
# Docker Compose
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
  db:
    image: postgres:16
    environment:
      POSTGRES_DB: myapp

Multi-Line Strings

YAML handles multi-line strings elegantly with block scalars:

# Literal block scalar — preserves newlines
description: |
  Line one.
  Line two.
  Line three.

# Folded block scalar — newlines become spaces
summary: >
  This long text will be
  folded into a single line
  when parsed.

JSON requires escaped \n:

{
  "description": "Line one.\nLine two.\nLine three."
}

YAML Pitfalls (The Norway Problem and Others)

YAML's type inference has caused real production incidents.

The Norway Problem

countries:
  - GB
  - DE
  - NO   # YAML 1.1 parses this as boolean false!
  - SE

In YAML 1.1 (used by many older parsers), no, NO, No are parsed as false. Similarly, yes, YES, Yes become true. YAML 1.2 (2009) removes this behavior, but many parsers still implement 1.1.

Other values affected in YAML 1.1: on, off, true, false, y, n, null, ~.

Fix: Quote values that might be misinterpreted:

countries:
  - "GB"
  - "DE"
  - "NO"   # Now safely a string
  - "SE"

Octal Number Parsing

file_permissions: 0777  # YAML 1.1: parses as octal 511, not decimal 777!
port: 0755              # octal 493

In YAML 1.2, leading zeros do not imply octal. In 1.1, they do. Quote numeric values where precision matters.

Indentation Errors

YAML uses only spaces — mixing tabs and spaces causes parser errors. Python developers familiar with tab-based indentation often hit this:

server:
  host: localhost
	port: 8080  # TAB here — YAML parse error!

Duplicate Keys

config:
  debug: true
  debug: false  # Which one wins? Undefined behavior

Different parsers handle duplicate keys differently (last wins, first wins, or error). JSON officially prohibits duplicate keys too, but behavior varies.

Conversion

// YAML to JSON (Node.js)
import yaml from "js-yaml";
import fs from "fs";

const yamlContent = fs.readFileSync("config.yaml", "utf8");
const parsed = yaml.load(yamlContent);
const json = JSON.stringify(parsed, null, 2);
import yaml, json

with open("config.yaml") as f:
    data = yaml.safe_load(f)  # Use safe_load, not load!

print(json.dumps(data, indent=2))

Always use yaml.safe_load() in Python, never yaml.load(). The unsafe version can execute arbitrary Python code via YAML deserialization — a known RCE vector.

Decision Guide

SituationChoose
REST API responsesJSON
gRPC / Protocol BuffersNeither (binary)
package.json, tsconfig.jsonJSON
Kubernetes manifestsYAML
GitHub Actions / CIYAML
Docker ComposeYAML
Ansible playbooksYAML
Config with comments neededYAML
Machine-generated configJSON
Human-authored configYAML
Data with many stringsYAML (no quoting needed)

Try It Now

Convert between JSON and YAML instantly with the JSON Formatter Tool and the YAML Formatter Tool — both run entirely in your browser.

More Tools from Cosyslabs

  • PDF Convert All — Convert, merge, and compress PDFs. Many document generation pipelines consume JSON or YAML configuration to drive PDF rendering — useful context for both formats.
  • Unit Convert All — Convert measurement values often found in configuration files (e.g., timeouts in ms, file sizes in MB) between units.
  • Rough Estimator — Estimate the effort of migrating JSON-based config systems to YAML (or vice versa) in a large codebase.
  • Cosyslabs — The studio behind Dev Tools !, Routine Toolkit, Astrilio, CastFleet, and more.