JSON ↔ YAML Converter

Convert between JSON and YAML in either direction. Clear error messages with line numbers.

Loading…

All processing runs in your browser — no files or inputs are uploaded to a server.

How to use

Toggle the direction (JSON → YAML or YAML → JSON), paste your source on the left, and the converted output appears on the right. The Swap button copies the current output back into the input pane and flips the direction — handy for round-tripping a config or sanity-checking a conversion in both directions. Parse errors are pinned to a line and column so structural issues are easy to find.

Reach for this when moving config between systems that prefer different formats — converting a Kubernetes manifest someone wrote in JSON into the YAML form `kubectl` expects, generating a Helm `values.yaml` from API output, or feeding a Terraform JSON variable file into a Kustomize patch. The two formats share the same data model (JSON is a strict subset of YAML 1.2), so for most config the round-trip is lossless. Everything runs in the browser via the `yaml` library — no upload, useful when the config contains internal hostnames or secrets.

Examples

Compact JSON → readable YAML

Input
{"name":"sample","version":"1.0.0","ports":[80,443],"env":{"production":true,"region":"us-east-1"}}
Output
name: sample
version: 1.0.0
ports:
  - 80
  - 443
env:
  production: true
  region: us-east-1

The most frequent use — turn machine-emitted JSON (an API response, a Terraform plan output) into the indented YAML that humans review in pull requests. The 2-space indent matches Kubernetes / Helm / GitHub Actions conventions.

YAML with comments → JSON (comments lost)

Input
# Production config
name: api
version: 1.0.0
replicas: 3 # bumped 2024-Q2
features:
  - search   # GA
  - billing  # beta
Output
{
  "name": "api",
  "version": "1.0.0",
  "replicas": 3,
  "features": [
    "search",
    "billing"
  ]
}

JSON has no comment syntax, so every `#` line and inline comment drops. Anchors (`&base`) and aliases (`*base`) are also expanded to their target values. If you need the comments preserved, keep the YAML source as the canonical form and re-render to JSON only at consumption time.

YAML date → JSON string

Input
name: release
released: 2024-05-27
expires: 2025-05-27T00:00:00Z
Output
{
  "name": "release",
  "released": "2024-05-27",
  "expires": "2025-05-27T00:00:00.000Z"
}

YAML knows date / timestamp scalar types; JSON does not. The converter serializes a `Date` object to its ISO 8601 string form when emitting JSON. If you JSON → YAML the result, the `released` field comes back as a string rather than a date — round-trip is not always type-preserving.

FAQ

Is the round-trip lossless?

For most JSON, yes — JSON is a strict subset of YAML 1.2, so JSON → YAML → JSON preserves every value. The other direction loses YAML-only features: comments, anchors and aliases (expanded inline), tagged types like `!!set` and `!!binary`, and rich scalar types like dates and infinity. If round-trip fidelity matters, keep the richer format (YAML) as your source of truth and generate JSON on demand.

My YAML has `anchors` and `aliases` — what happens?

They expand. An alias like `*default` is replaced by the value of the matching `&default` anchor, so the JSON output contains the same subtree repeated wherever the alias appeared. This is correct semantically but loses the deduplication intent. Going back JSON → YAML produces a fully-expanded YAML without anchors. If you need anchors preserved (long config files, k8s manifests with shared blocks), stay in YAML and use a YAML-native tool.

Does it handle multi-document YAML (separated by `---`)?

No — the converter assumes a single document. JSON has no native concept of multiple top-level documents, so converting a 5-document YAML would need to wrap them in an array (`[{...}, {...}, ...]`), which is a semantic change you should make explicitly. Run each document separately, or for the array-wrap pattern split the YAML on `^---$` lines first and join the results.

The output YAML uses `null` instead of empty — can I get the bare form?

YAML allows three forms for null: explicit `null`, the tilde `~`, and an empty value (`key:` with no value after the colon). The library defaults to explicit `null` for unambiguity — it round-trips safely and a future reader knows you meant null rather than forgetting to fill it in. If you must match a tool that strictly requires the bare form, post-process with `sed 's/: null$/:/g'`. The semantic meaning is identical.

YAML strings sometimes get quoted in the output — why?

The serializer quotes a string when leaving it bare would change its meaning. `"yes"` becomes `'yes'` to prevent YAML 1.1 parsers from reading it as the boolean true. `"123"` becomes `'123'` so it stays a string instead of an integer. Strings starting with `*`, `&`, `!`, `|`, `>` need quoting because those bytes have YAML meaning. The pattern is consistent: if a bare scalar would parse to a different type than the string you intended, the library quotes it.

How does this differ from the YAML Validator on this site?

Validator only — checks YAML syntax and lists errors with line numbers. Converter — parses the input, walks the in-memory tree, and re-emits in the other format. The converter implicitly validates (a parse failure produces an error), but it also performs the format switch. Use the validator when you just want a yes / no answer on a YAML file; use the converter when you actually need the other format.

Related concepts

JSON and YAML share the same logical data model — scalars, sequences, and mappings — so most converter work is renaming the syntax around the same tree. JSON is intentionally minimal: double-quoted strings, no comments, no trailing commas, four primitives (string, number, boolean, null) plus array and object. YAML 1.2 explicitly defines JSON as a valid subset, so any JSON document parses as YAML without changes. The arrow does not always reverse cleanly: YAML adds comments, anchors and aliases for deduplication, multi-document streams, block scalars (`|` preserves newlines, `>` folds), and tagged types (`!!set`, `!!binary`, `!!timestamp`) that JSON has no place for.

The practical split is **machine vs human consumer**. JSON dominates wire formats: REST API bodies, NoSQL document stores, browser `localStorage`, log shippers. Its rigidity is a feature — no comment lines accidentally breaking a parser, no whitespace ambiguity. YAML dominates human-edited configuration: Kubernetes manifests, GitHub Actions workflows, Ansible playbooks, Docker Compose files, Helm charts. Its flexibility (comments, multi-line strings, anchors) is what pays for the indentation pain. A common pattern is to author in YAML and ship JSON to runtime systems — `helm template` does exactly this.

Three adjacent formats are worth recognizing. **TOML** targets configuration like YAML but with stricter, less-ambiguous syntax — common in Rust `Cargo.toml`, Python `pyproject.toml`, and Hugo configs. **HCL** (HashiCorp Configuration Language) backs Terraform with block-oriented syntax and embedded expressions. **JSON5 / JSONC** retrofit comments and trailing commas onto JSON for human editing without leaving the JSON family — `tsconfig.json` and VS Code `settings.json` use the latter. Each picks a different point on the readability-vs-strictness spectrum; YAML and JSON occupy the two ends with the broadest tooling support.

Related articles

Related tools