How the two directions work
YAML 1.2 was designed so that valid JSON is also valid YAML, but the reverse is not true: YAML adds indentation-based nesting, comments and many unquoted scalars. This converter therefore treats the directions very differently. JSON to YAML first runs JSON.parse, so any malformed JSON stops with the browser's error before any output appears. YAML to JSON uses the open-source yaml library, a full YAML 1.2 parser that is downloaded the first time you convert YAML to JSON, so anchors, aliases, tags and multi-line scalars all convert.
JSON to YAML: what the writer does
Nested objects are indented by two spaces. Array items start with - at the same indent as their parent key, which is valid YAML and common in Kubernetes manifests. Empty arrays and objects become [] and {}. Strings are written bare only when they start with a letter and contain letters, digits, spaces, dots, hyphens, underscores or slashes, do not end with a space, and are not words YAML 1.1 reads as booleans or null. Anything else is double-quoted: empty strings, leading or trailing spaces, colons, hashes, quotes, line breaks and other control characters, so every string reads back exactly as it was.
{"server":{"host":"localhost","port":8080,"tls":false},
"routes":[{"path":"/a","auth":true}],"owner":"no"}
server:
host: localhost
port: 8080
tls: false
routes:
- path: "/a"
auth: true
owner: "no"
Note that "/a" and "no" are quoted. The path starts with a slash, and no would be read as boolean false by older YAML parsers. A string like "2024-01-01" or "1.0" is also quoted so that it stays text rather than turning into a date or number. Keys follow the same rule, so a key named n is written as "n".
YAML to JSON: what is read
| Feature | How it converts |
|---|---|
Nested maps and - sequences, including - - x on one line | Objects and arrays |
Anchors and aliases (&base, *base) | The alias is replaced by a copy of the anchored value |
Merge keys (<<: *base) | The keys of the merged map are added, and keys written next to << win |
Tags such as !!str 123 and !!int "42" | The tag sets the type, so !!str 123 is the string "123" |
| Multi-line plain and quoted scalars | Line breaks fold into single spaces, and a blank line becomes a line break |
Block scalars | and >, with chomping (|-, |+, >-) and indentation indicators | Strings, as described below |
Flow lists and maps such as [a, b] and {a: 1, b: [x, y]}, including over several lines | Arrays and objects |
Complex keys (? ) | Accepted, but JSON keys must be text, so a collection used as a key is written as its text form |
# comments and multi-document files | Comments are dropped, and documents are described below |
Numbers (including 0x hex and 0o octal), true, false, null, ~ | The matching JSON values |
yes, no, on, off and dates such as 2024-01-01 | Stay strings, as YAML 1.2 defines. A file that starts with %YAML 1.1, or a value tagged !!timestamp, is read as a date instead and written as ISO 8601 text in UTC ("2024-01-01", or the full date and time when a time is given), with a note |
Some inputs cannot be carried over exactly. A tag the parser does not know, such as !Ref, is dropped and its value is kept as plain text, with a note under the result. JSON has no sets, ordered maps or binary data, so !!set becomes an array of its keys, !!omap an array of one-key objects and !!binary a base64 string, again with a note. .inf and .nan have no JSON form and become null, also with a note. An alias that points back at its own parent would make a loop, so it is reported as an error.
Block scalars
A literal block (|) keeps line breaks and a folded block (>) joins lines with spaces, with a blank line becoming a line break and more-indented lines kept as they are. By default the text ends with one newline (clip), - removes it (strip) and + keeps every trailing blank line. Lines in the block that start with # are text, not comments. For d: | followed by two indented lines, line1 and line2, the JSON value is "line1\nline2\n", and the keys after it are still read.
Multiple documents
If the input holds several documents separated by --- (or ended with ...), the output is a JSON array with one entry per document, and a note above the result says how many were found. A single document, even with a leading ---, converts to its own value, not an array. Because of that, a file with one document that is itself a list cannot be told apart from a list of documents by shape alone, so check the note.
Errors and edge cases
- Invalid YAML stops with an error that names the line, so you never get a result with data silently missing. A line indented deeper than expected, a tab used as indentation or an unclosed flow list are all reported.
- A key that appears twice in the same mapping is an error that names the line, instead of the second value silently replacing the first.
- An alias that refers to an anchor that was never defined is an error that names the line of the alias, because anchors must come before the alias that uses them. A file whose aliases expand into more than 10,000 references is refused, which stops nested-alias bombs. When the parser cannot say where a mistake is, the message names the document instead of a line.
- Quoted strings follow YAML escaping:
\"inside double quotes does not end the string,''inside single quotes is one apostrophe, and an apostrophe in an unquoted value such asdon'tis just text, so a# commentafter it is still recognised. 007becomes the number 7, andyesstays the string"yes".
Tidy JSON first with the JSON formatter, or move tabular data with JSON to CSV and JSON to XML.