DevToolBoxFREE
Blog

YAML to JSON: Convert Online with JavaScript, Python, and CLI Tools

7 min readby DevToolBox

YAML to JSON: Convert Online with JavaScript, Python, and CLI Tools

Convert YAML to JSON online and with code. Complete guide for JavaScript, Python, Go, and command-line YAML-to-JSON conversion.

TL;DR

YAML is the human-readable config format; JSON is the universal language of APIs. Convert online with DevToolBox's free tool; use js-yaml (JavaScript), PyYAML (Python), or gopkg.in/yaml.v3 (Go) in code; use yq on the command line. Watch out for YAML boolean traps (yes/no/on/off), forbidden tabs, and anchor expansion. Multi-document YAML (--- separator) converts to a JSON array.

YAML vs JSON — Key Differences

YAML (YAML Ain't Markup Language) and JSON (JavaScript Object Notation) are both data serialization formats, but with fundamentally different design philosophies. YAML is optimized for human editing with indentation-based nesting; JSON is optimized for machine parsing with strict, unambiguous syntax. The table below compares key differences in real-world use:

FeatureYAMLJSON
ReadabilityExcellent — indentation syntax, minimal punctuationModerate — many quotes and brackets
Comments SupportYes — lines starting with #Not supported
Data TypesStrings, ints, floats, booleans, null, dates, binaryStrings, numbers, booleans, null, arrays, objects
File SizeGenerally smaller — no quotes or braces requiredSlightly larger due to required syntax characters
Parsing SpeedSlower — indentation-sensitive parsingFaster — simpler grammar, widely optimized
Use CaseKubernetes, Docker Compose, CI/CD, Ansible configREST APIs, databases, machine-to-machine exchange

Online Conversion

The fastest way to convert YAML to JSON is using an online tool. The DevToolBox YAML to JSON converter provides real-time preview, error highlighting, and formatted output — no installation required. It is ideal for one-off conversions, debugging configuration files, or verifying YAML syntax before committing to a repository.

For scenarios requiring integration into engineering workflows or automation pipelines, continue reading for language-specific code examples and command-line approaches.

JavaScript / Node.js — Using js-yaml

The js-yaml library is the most popular YAML parser in the JavaScript ecosystem, compatible with both Node.js and browser environments. The core API is yaml.load() to parse YAML into a JavaScript object, and JSON.stringify() to serialize it as JSON.

Install:

npm install js-yaml
# TypeScript types are bundled — no @types needed

Basic conversion:

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

const yamlString = `
name: my-app
version: 1.0.0
database:
  host: localhost
  port: 5432
  credentials:
    user: admin
    password: secret
features:
  - auth
  - logging
  - metrics
enabled: true
`;

// Parse YAML → JavaScript object
const obj = yaml.load(yamlString);

// Serialize to JSON (pretty-printed with 2-space indent)
const json = JSON.stringify(obj, null, 2);
console.log(json);

/* Output:
{
  "name": "my-app",
  "version": "1.0.0",
  "database": {
    "host": "localhost",
    "port": 5432,
    "credentials": {
      "user": "admin",
      "password": "secret"
    }
  },
  "features": ["auth", "logging", "metrics"],
  "enabled": true
}
*/

Converting a YAML file:

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

function yamlFileToJson(inputPath, outputPath) {
  // Read YAML file
  const yamlContent = fs.readFileSync(inputPath, 'utf8');

  // Parse and convert
  const obj = yaml.load(yamlContent);
  const jsonContent = JSON.stringify(obj, null, 2);

  // Write JSON file
  if (outputPath) {
    fs.writeFileSync(outputPath, jsonContent, 'utf8');
    console.log(`Converted ${inputPath} → ${outputPath}`);
  }

  return jsonContent;
}

// Usage
yamlFileToJson('config.yaml', 'config.json');
yamlFileToJson('k8s-deployment.yaml', 'k8s-deployment.json');

Handling multi-document YAML (--- separator):

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

const multiDocYaml = `
---
kind: Deployment
metadata:
  name: api-server
---
kind: Service
metadata:
  name: api-service
---
kind: ConfigMap
metadata:
  name: api-config
`;

// yaml.load() only parses the FIRST document
// Use yaml.loadAll() for multi-document YAML
const documents = yaml.loadAll(multiDocYaml);

console.log(`Found ${documents.length} documents`);
// Convert the document array to JSON
const json = JSON.stringify(documents, null, 2);
console.log(json);

// Or process each document individually
documents.forEach((doc, index) => {
  console.log(`Document ${index + 1}: ${doc.kind}`);
});

Python — Using PyYAML

PyYAML is the standard YAML library for Python. Always use yaml.safe_load() instead of yaml.load() to prevent arbitrary code execution from untrusted YAML input — yaml.load() with untrusted data is a known security vulnerability.

Install:

pip install pyyaml

Basic conversion:

import yaml
import json

yaml_string = """
server:
  host: 0.0.0.0
  port: 8080
  timeout: 30
database:
  url: postgres://localhost/mydb
  pool_size: 10
  ssl: true
logging:
  level: info
  format: json
tags:
  - production
  - api
  - v2
"""

# Parse YAML safely (prevents code execution from untrusted YAML)
data = yaml.safe_load(yaml_string)

# Serialize to JSON with indentation
json_output = json.dumps(data, indent=2)
print(json_output)

# Output:
# {
#   "server": { "host": "0.0.0.0", "port": 8080, "timeout": 30 },
#   "database": { "url": "postgres://localhost/mydb", "pool_size": 10, "ssl": true },
#   "logging": { "level": "info", "format": "json" },
#   "tags": ["production", "api", "v2"]
# }

Converting files:

import yaml
import json
import sys
from pathlib import Path

def yaml_to_json(input_path: str, output_path: str = None) -> str:
    """Convert a YAML file to JSON."""
    with open(input_path, 'r', encoding='utf-8') as f:
        data = yaml.safe_load(f)

    json_str = json.dumps(data, indent=2, ensure_ascii=False)

    if output_path:
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(json_str)
        print(f"Converted {input_path} → {output_path}")

    return json_str

# Convert a single file
result = yaml_to_json("config.yaml", "config.json")

# Convert multiple files in a directory
for yaml_file in Path(".").glob("**/*.yaml"):
    json_file = yaml_file.with_suffix(".json")
    yaml_to_json(str(yaml_file), str(json_file))

Multi-document YAML with yaml.safe_load_all():

import yaml
import json

multi_doc_yaml = """
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-api
spec:
  replicas: 3
---
apiVersion: v1
kind: Service
metadata:
  name: web-api-svc
spec:
  type: ClusterIP
  port: 80
"""

# yaml.safe_load() only reads the first document
# yaml.safe_load_all() returns a generator for all documents
documents = list(yaml.safe_load_all(multi_doc_yaml))

print(f"Found {len(documents)} documents")
# Serialize the entire array to JSON
print(json.dumps(documents, indent=2))

Command Line Tools

Command-line conversion is ideal for shell scripts, CI/CD pipelines, and quick one-off operations. Here are the most commonly used approaches:

yq (recommended):

# Install yq (macOS)
brew install yq

# Install yq (Linux)
sudo wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
sudo chmod +x /usr/local/bin/yq

# Convert YAML file to JSON
yq -o json config.yaml

# Convert and save to file
yq -o json config.yaml > config.json

# Pretty-print with indentation
yq -o json -P config.yaml

# Convert from stdin
cat config.yaml | yq -o json

# Process specific keys during conversion
yq -o json '.database' config.yaml

# Convert multiple files
for f in *.yaml; do yq -o json "$f" > "${f%.yaml}.json"; done

Python one-liner (no extra installation):

# Convert YAML stdin to JSON stdout
cat file.yaml | python3 -c "import yaml,json,sys; print(json.dumps(yaml.safe_load(sys.stdin), indent=2))"

# Convert YAML file to JSON file
python3 -c "
import yaml, json
with open('input.yaml') as f:
    data = yaml.safe_load(f)
with open('output.json', 'w') as f:
    json.dump(data, f, indent=2)
"

# One-liner with file args
python3 -c "import yaml,json,sys; json.dump(yaml.safe_load(open(sys.argv[1])), open(sys.argv[2],'w'), indent=2)" input.yaml output.json

Ruby one-liner:

# Ruby one-liner (available on most Unix systems)
ruby -ryaml -rjson -e 'puts JSON.pretty_generate(YAML.safe_load(STDIN.read))' < file.yaml

YAML Data Type Mapping to JSON

Understanding how YAML types map to JSON types is essential for avoiding conversion surprises. The following table shows common YAML type mappings:

YAML ValueJSON OutputNotes
null, ~, (empty)nullYAML null values
true, falsetrue, falseBooleans in YAML 1.1 and 1.2
yes, no, on, offtrue, falseOnly in YAML 1.1 — always quote these
42, -742, -7Integer numbers
3.14, 1.0e103.14, 1.0e10Floating-point numbers
0777 (octal)511Octal notation becomes decimal integer
0xFF (hex)255Hex notation becomes decimal integer
"hello", 'world'"hello", "world"Strings (quotes optional in YAML)
!!binary <base64>"<base64>"Binary data becomes base64 string
&anchor, *aliasExpanded valueAnchors and aliases fully dereferenced
- item1 - item2["item1", "item2"]YAML sequences become JSON arrays
key: value{"key": "value"}YAML mappings become JSON objects

YAML Anchors and Aliases

YAML anchors (&) define reusable data blocks, and aliases (*) reference them. During JSON conversion, all aliases are fully dereferenced (expanded inline) — JSON has no reference mechanism. Merge keys (<<: *base) are also expanded, with later keys overriding earlier ones.

Before conversion (YAML):

# YAML with anchors and aliases
defaults: &defaults
  timeout: 30
  retries: 3
  log_level: info

production:
  <<: *defaults          # Merge: inherits timeout, retries, log_level
  log_level: warning     # Override: replaces log_level from defaults
  replicas: 5

staging:
  <<: *defaults          # Merge: inherits all defaults
  replicas: 1

# Simple alias (not merge key)
base_image: &img "node:20-alpine"
services:
  web:
    image: *img          # Alias: becomes "node:20-alpine"
  worker:
    image: *img          # Alias: also becomes "node:20-alpine"

After conversion (JSON) — anchors fully expanded:

{
  "defaults": { "timeout": 30, "retries": 3, "log_level": "info" },
  "production": {
    "timeout": 30,
    "retries": 3,
    "log_level": "warning",
    "replicas": 5
  },
  "staging": {
    "timeout": 30,
    "retries": 3,
    "log_level": "info",
    "replicas": 1
  },
  "base_image": "node:20-alpine",
  "services": {
    "web": { "image": "node:20-alpine" },
    "worker": { "image": "node:20-alpine" }
  }
}

Note: The JSON output is larger than the YAML source because every aliased value is fully duplicated. In configurations with heavy anchor reuse, this can significantly increase JSON file size.

Multi-Document YAML

YAML supports multiple documents in a single file, separated by ---. This is extremely common in Kubernetes (one YAML file containing a Deployment + Service + ConfigMap). When converting to JSON, multi-document YAML becomes a JSON array where each element is one document.

# Multi-document YAML (common in Kubernetes)
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 8080

JavaScript — yaml.loadAll():

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

const content = fs.readFileSync('k8s-manifests.yaml', 'utf8');

// yaml.load() → only parses FIRST document (wrong for multi-doc)
// yaml.loadAll() → parses ALL documents into an array
const documents = yaml.loadAll(content);

console.log(JSON.stringify(documents, null, 2));
// Result: [{ apiVersion: "apps/v1", kind: "Deployment", ... }, { apiVersion: "v1", kind: "Service", ... }]

yq command line:

# yq automatically handles multi-document YAML
# Outputs as JSON array
yq -o json k8s-manifests.yaml

# Split into individual JSON files
yq -o json '.' k8s-manifests.yaml | jq -c '.[]' | while read doc; do
  kind=$(echo "$doc" | jq -r '.kind')
  echo "$doc" | jq . > "${kind,,}.json"
done

Go — gopkg.in/yaml.v3 + encoding/json

Go uses gopkg.in/yaml.v3 to parse YAML and the standard library encoding/json to serialize JSON. Go's strong typing makes conversion explicit and controlled. You can use interface{} for dynamic handling or define structs for type safety.

// go get gopkg.in/yaml.v3

package main

import (
    "encoding/json"
    "fmt"
    "os"

    "gopkg.in/yaml.v3"
)

// Dynamic approach — works for any YAML structure
func yamlToJsonDynamic(yamlBytes []byte) ([]byte, error) {
    // Step 1: Parse YAML into generic interface{}
    var obj interface{}
    if err := yaml.Unmarshal(yamlBytes, &obj); err != nil {
        return nil, fmt.Errorf("yaml parse error: %w", err)
    }

    // Step 2: Serialize to JSON
    jsonBytes, err := json.MarshalIndent(obj, "", "  ")
    if err != nil {
        return nil, fmt.Errorf("json marshal error: %w", err)
    }

    return jsonBytes, nil
}

// Struct-based approach — type-safe, best for known schemas
type Config struct {
    Name    string `yaml:"name" json:"name"`
    Version string `yaml:"version" json:"version"`
    Server  struct {
        Host string `yaml:"host" json:"host"`
        Port int    `yaml:"port" json:"port"`
    } `yaml:"server" json:"server"`
    Features []string `yaml:"features" json:"features"`
}

func main() {
    yamlContent := []byte(`
name: my-service
version: "2.1.0"
server:
  host: 0.0.0.0
  port: 8080
features:
  - auth
  - rate-limiting
  - tracing
`)

    // Dynamic approach
    jsonBytes, err := yamlToJsonDynamic(yamlContent)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v\n", err)
        os.Exit(1)
    }
    fmt.Println(string(jsonBytes))

    // Struct-based approach
    var cfg Config
    if err := yaml.Unmarshal(yamlContent, &cfg); err != nil {
        panic(err)
    }
    out, _ := json.MarshalIndent(cfg, "", "  ")
    fmt.Println(string(out))
}

Kubernetes and CI/CD Use Cases

Converting YAML to JSON has several practical applications in DevOps workflows:

1. Interacting with the Kubernetes API:

# kubectl can apply both YAML and JSON
# Convert k8s manifest YAML to JSON for API calls
yq -o json deployment.yaml > deployment.json

# Use with curl to call the Kubernetes API directly
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  https://$K8S_API/apis/apps/v1/namespaces/default/deployments \
  -d @deployment.json

# Validate manifest before applying
kubectl apply --dry-run=client -f deployment.yaml
yq -o json deployment.yaml | kubectl apply --dry-run=client -f -

2. GitHub Actions workflow conversion:

# GitHub Actions step to convert YAML config to JSON for downstream tools
- name: Convert YAML config to JSON
  run: |
    pip install pyyaml
    python3 -c "
    import yaml, json
    with open('config.yaml') as f:
        data = yaml.safe_load(f)
    with open('config.json', 'w') as f:
        json.dump(data, f, indent=2)
    "
    echo "Config converted:"
    cat config.json

# Or using yq in GitHub Actions
- name: Convert with yq
  uses: mikefarah/yq@master
  with:
    cmd: yq -o json config.yaml > config.json

3. Helm values.yaml to JSON for Terraform:

# Convert Helm values.yaml to JSON for use in Terraform helm_release
yq -o json values.yaml > values.json

# In Terraform:
# resource "helm_release" "app" {
#   values = [file("values.json")]
# }

# Or generate Terraform variables from YAML config
python3 -c "
import yaml, json
with open('app-config.yaml') as f:
    config = yaml.safe_load(f)

# Write as Terraform tfvars JSON
with open('terraform.tfvars.json', 'w') as f:
    json.dump(config, f, indent=2)
"

Common Pitfalls and Edge Cases

1. The Boolean Trap (YAML 1.1)

YAML 1.1 treats a surprisingly large set of values as booleans. This is the most common source of conversion bugs:

# YAML 1.1 boolean trap — these all become true or false in JSON!
country: NO           # → false  (Norway country code!)
debug: yes            # → true
feature_flag: on      # → true
cache: off            # → false
verbose: y            # → true  (short form)
quiet: n              # → false (short form)

# Fix: always quote ambiguous strings
country: "NO"         # → "NO"  (string)
debug: "yes"          # → "yes" (string)
feature_flag: "on"    # → "on"  (string)

# YAML 1.2 only treats these as booleans:
# true, false (case-insensitive)
# All other values are strings

2. Octal Numbers (0777 → 511)

# File permissions as octal numbers become decimal integers!
chmod_value: 0777    # → 511 in JSON (not "0777"!)
umask: 022           # → 22 in JSON

# Fix: quote the value to keep it as a string
chmod_value: "0777"  # → "0777" (string)
umask: "022"         # → "022" (string)

# Or use explicit YAML tag
chmod_value: !!str 0777  # → "0777"

3. Multiline Strings (| literal vs > folded)

# Literal block (|) — preserves newlines exactly
script: |
  #!/bin/bash
  echo "Starting..."
  npm install
  npm test
# JSON: "#!/bin/bash
echo "Starting..."
npm install
npm test
"

# Folded block (>) — joins lines with spaces (like HTML)
description: >
  This is a long
  description that
  wraps across lines.
# JSON: "This is a long description that wraps across lines.
"

# Chomping indicators control trailing newlines:
# | (default) → keeps exactly one trailing newline
# |- → strips all trailing newlines
# |+ → keeps all trailing newlines

4. Tabs Are Forbidden

# WRONG: tabs cause parse errors
server:
	host: localhost    # ← tab character → YAML parse error!
	port: 8080

# CORRECT: always use spaces (2 is the convention)
server:
  host: localhost    # ← 2 spaces
  port: 8080

# Configure your editor to insert spaces (not tabs) for .yaml files
# .editorconfig:
# [*.{yaml,yml}]
# indent_style = space
# indent_size = 2

Reverse: JSON to YAML

Converting JSON to YAML is equally straightforward. Every major YAML library supports this direction. Keep in mind: comments cannot survive a JSON round-trip since JSON has no comment syntax.

JavaScript (js-yaml):

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

const jsonObj = {
  name: "my-app",
  version: "1.0.0",
  server: { host: "0.0.0.0", port: 8080 },
  features: ["auth", "logging"]
};

// yaml.dump() converts JS object → YAML string
const yamlOutput = yaml.dump(jsonObj, {
  indent: 2,        // 2-space indentation
  lineWidth: 120,   // wrap at 120 chars
  noRefs: true,     // don't use aliases in output
});

console.log(yamlOutput);
// name: my-app
// version: 1.0.0
// server:
//   host: 0.0.0.0
//   port: 8080
// features:
//   - auth
//   - logging

Python (PyYAML):

import yaml
import json

json_string = '{"name":"my-app","server":{"host":"localhost","port":8080},"tags":["api","v2"]}'
data = json.loads(json_string)

# yaml.dump() serializes Python dict → YAML string
yaml_output = yaml.dump(data, default_flow_style=False, indent=2, allow_unicode=True)
print(yaml_output)
# name: my-app
# server:
#   host: localhost
#   port: 8080
# tags:
# - api
# - v2

yq reverse conversion:

# Convert JSON to YAML with yq
yq -oy config.json            # -o yaml (can also use --output-format=yaml)
yq -oy config.json > config.yaml

# Convert JSON stdin to YAML
echo '{"name":"app","port":3000}' | yq -oy
Key Takeaways
  • YAML is for human-edited config files (Kubernetes, Docker Compose, GitHub Actions); JSON is for APIs and machine-to-machine communication.
  • Use DevToolBox's online tool for quick conversions; js-yaml (JavaScript), PyYAML (Python), gopkg.in/yaml.v3 (Go) for code; yq for the command line.
  • Always use yaml.safe_load() in Python — yaml.load() is a known code execution vulnerability with untrusted input.
  • Boolean trap: yes/no/on/off/y/n are all booleans in YAML 1.1. Always quote strings that could be misread as booleans.
  • YAML anchors (&) and aliases (*) are fully expanded in JSON output — the resulting JSON may be larger than the YAML source.
  • Multi-document YAML (--- separator) requires yaml.loadAll() or yaml.safe_load_all() and converts to a JSON array.
  • YAML forbids tab characters for indentation — always use spaces (2 is the convention). Enforce with .editorconfig in your editor.
𝕏 Twitterin LinkedIn
Was this helpful?

Stay Updated

Get weekly dev tips and new tool announcements.

No spam. Unsubscribe anytime.

Try These Related Tools

Y→YAML to JSON Converter{ }JSON FormatterJSON Validator

Related Articles

YAML to JSON Converter: Complete Guide with Code Examples

Free online YAML to JSON converter. Learn YAML syntax, convert between YAML and JSON, avoid common pitfalls with code examples in JavaScript, Python, Go, and Bash.

YAML vs JSON: Syntax Comparison, When to Use Each, and How to Convert

Compare YAML and JSON syntax, features, and use cases. Learn about YAML anchors, multiline strings, Docker/Kubernetes configs, and how to convert between formats.

JSON to YAML Converter Online Guide: Syntax, Tools, and Best Practices

Complete guide to converting between JSON and YAML. Covers syntax comparison, js-yaml, PyYAML, ruamel.yaml, yq CLI, Kubernetes manifests, Docker Compose, YAML gotchas (Norway problem, booleans), and security best practices.