JSON to YAML and YAML to JSON converter
<< merge keys are resolved and a multi-document file becomes an array. Everything runs in your browser — nothing is uploaded.Input
emptyYAML
Every JSON document is already valid YAML
This is the part that surprises people: YAML 1.2 is a strict superset of JSON, so you could rename config.json to config.yaml and most parsers would accept it unchanged. Converting is therefore not about making the document work — it is about making it readable, and about the two things YAML adds that JSON has no form for: comments, and block scalars for long text.
So the honest reason to convert is a human one. A 40-line JSON object with three levels of braces becomes a 40-line YAML document with no braces at all, and once it is YAML you can write a comment next to the setting nobody understands. The reverse direction is a machine one: you need JSON because something downstream only parses JSON.
The round trip is not always lossless, and here is exactly where
Converting one way and back is the thing this page makes easy, so it is worth being blunt about where it does not return what you started with. Nothing below is a bug in the converter; each one is a place the two formats genuinely disagree.
- Anchors do not survive. YAML can write a value once and alias it; JSON cannot, so each alias expands into a copy. Convert back and you get the copies, not the anchor.
- Comments do not survive. JSON has no comment syntax, so YAML → JSON drops them and nothing can bring them back.
- Several documents become one array. A
----separated file converts to a JSON array; converting that back gives one YAML document containing a list. .infand.nanbecomenull. JSON has no way to write either. A note says so when it happens.
yes and no are strings, not booleans
The single most common YAML surprise, and worth being precise about. YAML 1.1 treated yes, no, on and off as booleans. YAML 1.2 removed that: only true and false are booleans, in any of the casings true, True or TRUE.
This converter follows YAML 1.2, so enabled: no becomes "enabled": "no" — a string. If the tool that consumes your file follows YAML 1.1, it will read the same line as false. That disagreement is real and it is why the advice is always to quote the value, or write false outright.
The related trap has a name — the Norway problem, where a country list containing NO lost Norway to a boolean. Under 1.2 it does not happen: NO stays the string "NO".
Why some strings come out quoted
Going to YAML, if your JSON contains "version": "3.10", the result says version: '3.10' — with quotes. Without them YAML would read that value back as the number 3.1, and your version would change. The same applies to "007", "true", "null" and "123".
The quoting is not decoration and it is not removable: it is the only thing keeping the round trip honest. A converter that emitted version: 3.10 would produce a document that looks tidier and holds different data.
Coming the other way the same rule bites in reverse. An unquoted 007 is the number 7 and the padding is gone; 0x1F is 31. That is correct YAML, and it is also how a zero-padded account code quietly changes meaning. The fix is in the source document — quote it. Dates are safer than you might expect: 2026-08-17 stays the string "2026-08-17", because the YAML 1.2 core schema has no timestamp type.
Key order is preserved, and never sorted
Keys come out in the order they went in. Some converters sort alphabetically, which is defensible for a data format — JSON objects are formally unordered — but it is the wrong default when the output is a config file a person will read, where grouping is deliberate. The one exception is inherited from JavaScript rather than chosen here: integer-like keys sort ahead of everything else, exactly as they do in the JSON beautifier.
Anchors, aliases and merge keys
YAML can define a value once with an anchor (&base) and reuse it with an alias (*base). JSON has no such reference, so each alias is expanded into a full copy. Expect the JSON to be larger than the YAML, and expect the sharing to be gone — editing one copy afterwards no longer changes the others.
Merge keys (<<: *base) are resolved properly rather than left as a literal key called <<. That is a deliberate choice: strictly, the merge key is a YAML 1.1 feature that 1.2 did not carry over, but docker-compose files, GitLab CI pipelines and Helm values lean on it constantly, and a converter that produced a "<<" key would be technically defensible and useless.
Going the other way, repeated values are written out in full rather than turned back into anchors. Emitters often create them automatically when the same object appears twice, which produces a shorter file containing a feature you never asked for and may not recognise.
Files holding more than one document
A --- separator starts a new document, and a single Kubernetes manifest routinely holds five. JSON has no multi-document form, so a file with more than one document converts to a JSON array, one item per document, in order. A note appears above the output saying how many were found — silently converting only the first, which is what a naive parser does, would throw away most of your file.
What this refuses, and why
Two things are rejected rather than approximated. !!binary has no JSON equivalent, and the plausible workarounds either produce an object of numbered bytes or silently invent a base64 string that was not in your data — if that is what you actually want, the base64 tool does it explicitly. Duplicate keys are an error too — JSON would keep the last one and drop the rest, and a config file with the same key twice is a bug you want to know about.
Long strings
Long values are kept on one line rather than folded across several. Folding is valid YAML and round-trips correctly, but a string wrapped onto a second indented line scans as a second value to anyone reading quickly — and it only happens where there are spaces to fold at, so similar-looking inputs would behave differently.
What to reach for next
If your JSON is not parsing in the first place, the JSON validator gives the exact line and column. Once you have JSON, the JSON diff compares two documents as data rather than as text, which is the practical way to see what actually changed between two versions of a manifest.
Nothing is uploaded
Both directions run in your own browser. That matters more than usual here, because the documents people convert are configuration — Kubernetes manifests, CI pipelines, deployment values — and those routinely carry hostnames, bucket names and credentials. Nothing you paste is transmitted, stored or logged.