YAML to JSON Converter
Convert YAML to JSON or JSON to YAML with anchors, multi-document streams and type quirks handled honestly — entirely on this device.
How a --- multi-document stream converts: one JSON array, only the first document, or a refusal. YAML timestamps become ISO 8601 strings, or stay exactly as written. .nan and .inf have no JSON form — refuse, or write null with a warning. Collection keys have no JSON form — write them as quoted flow-scalar text instead of refusing.
Press ? for shortcuts
Do it offline:$ yq -o=json '.' config.yaml
How to use it
- Type, paste or drop a file up to 20 MB — the badge names the detected direction, and clicking it (or pressing s) flips the conversion.
- Set per-direction options: indentation, multi-document policy, date and non-finite handling one way; quoting, collection layout and line folding the other.
- Read the fidelity banner under the output — it counts every expanded anchor, dropped comment, resolved tag and coerced key from this run.
- Copy the result, download it as .json or .yaml, or let Share pack the tool state into the link.
Paste YAML to get JSON, or JSON to get YAML — the tool detects which one arrived, and the badge takes one click to override. Anchors expand with a count, a multi-document stream becomes a JSON array, integers past 2^53 keep every digit, and whatever JSON cannot carry — comments, tags, native timestamps — is counted in a banner instead of vanishing quietly. Documents up to 20 MB convert on this device.
How it works
YAML composes into a document model; nothing is edited as text. Merge keys and aliases resolve against their anchors under a 400-alias budget — expansion bombs refuse instead of hanging — tags settle into plain values, and one walk counts everything about to change. The JSON writer then prints from the resolved tree, keeping integer digits intact past 2^53.
The counts exist because the formats disagree on what a document holds. An expanded anchor becomes a copy at each alias position — same data, sharing gone. A dropped comment is deleted outright; JSON has no spelling for one. Each fact is a banner line with its count, so lossy never means quiet.
Examples
# defaults
x-img: &img nginx:1.25
web:
image: *img
replicas: 3
{
"x-img": "nginx:1.25",
"web": {
"image": "nginx:1.25",
"replicas": 3
}
}The alias becomes a second copy, and the banner reports 1 anchor expanded (1 alias reference resolved) beside 1 comment dropped — JSON has no comment syntax.
{"replicas": 3, "image": "nginx:1.25"}replicas: 3
image: nginx:1.25
Minimal quoting writes nginx:1.25 plain because it reads back as the same string; anything that would re-read as a number or boolean is quoted automatically.
kind: Service
---
kind: Deployment
---
kind: ConfigMap
[
{
"kind": "Service"
},
{
"kind": "Deployment"
},
{
"kind": "ConfigMap"
}
]The banner states 3 YAML documents converted into a JSON array. The first policy keeps only the lead document, noted; error refuses streams.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Quotes keep 1.20 a version string, not a number
Unquoted, 1.20 is a float and prints as 1.2; quoted, it stays a string. Writing YAML, values like "1.20" or "true" gain quotes so their type survives; plain no stays a string under this converter's YAML 1.2 rules.
Repeated keys convert, with the collision on record
The later value wins and a warning names the key with both line numbers involved. Twenty collisions get listed; past that, one sentinel says how many more went unlisted.
Unquoted dates become visible ISO 8601 strings
A bare 2001-12-14 matches YAML's timestamp form and JSON has no date type, so the default writes 2001-12-14T00:00:00.000Z and counts it. Setting dates to original passes the scalar through as typed.
!!binary payloads land as base64 text
The tag decodes to raw bytes, and JSON has nowhere to put bytes — they re-encode as a base64 string, counted, decoding back to the identical payload.
YAML keys can be almost anything; JSON keys are strings
404: Not Found carries the integer key 404, coerced to "404" and counted. Collection keys refuse by default; Stringify complex keys writes their flow-scalar text instead.
What a round trip loses
The return trip yields working YAML, not your file: comments are gone, aliases return as expanded copies. The banner counts list what to restore by hand.
Common errors
Tabs are not allowed as indentation at line 2, column 1 — probable cause: YAML forbids tabs as indentation; replace the tab with spaces.- YAML reserves tabs, so a tab-indenting editor trips this on its first nested line. The caret frame marks the spot — reindent with spaces and the rest usually parses unchanged.
A mapping key at line 1, column 3 is a sequence — JSON object keys must be strings; enable "Stringify complex keys" to convert it to flow-scalar text.- The explicit ? syntax permits collections as keys; JSON has no such shape. With the named toggle on, the key [ a, b ] becomes the string "[ a, b ]" and a note counts the rewrite.
`.nan` at line 1, column 8 is not a finite number — JSON has no NaN or Infinity; set non-finite handling to "null" to emit null instead.- YAML spells .nan, .inf and -.inf; JSON spells none of them, so strict mode stops. The lenient setting writes null in their place and warns with the count.
Unexpected "'" at line 1, column 2 — probable cause: single-quoted strings are JSON5, not JSON; use double quotes.- JSON-side failures come from the same validator engine the site's JSON tools run, position and hypothesis included. Swap the quotes for double quotes and the conversion proceeds.
FAQ
What happens to comments and anchors when YAML becomes JSON?
Comments are removed — JSON has no syntax for them — and each alias becomes a full copy of its anchor, every change counted in the banner. Expansion past the 400-alias budget, or a node that contains itself, refuses with a typed error.
How are multi-document YAML streams converted?
Each document between --- markers converts into one JSON array by default, with a note saying how many went in. The first policy keeps the lead document only; error refuses streams outright. An empty document converts to null rather than disappearing.
Why did a value change type between YAML and JSON?
Plain scalars carry type by spelling: 1.20 is a float printing as 1.2, a bare 2001-12-14 is a timestamp, and .nan has no JSON form. Quoted scalars stay strings. Integers past 2^53 reach JSON digit-intact; pasting that JSON back raises a precision warning, because standard parsers round there.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Convert now — above 2 MB the tool waits for this key.
- ⌘/Ctrl + S
- Download as .json or .yaml, following the direction.
- ⌘/Ctrl + C
- Copy the whole output when nothing is selected.
- ⌘/Ctrl + Shift + C
- Copy the whole output despite a selection.
- s
- Swap direction; one undo restores.
- t
- Next color theme.
- ? or ⌘/Ctrl + /
- Open the shortcut overlay.
- Esc
- Dismiss the topmost overlay; panes stay put.