Why convert between YAML and JSON at all?
The two formats describe the same thing — maps, lists, strings, numbers, booleans and null — with opposite priorities. JSON optimises for machines: one unambiguous way to write each value, punctuation that a parser can follow without counting spaces, and a grammar small enough to fit on a postcard. YAML optimises for humans: no braces, no quotes when they are not needed, comments, and multi-line strings that read like prose. Which is why configuration lives in YAML and wire protocols live in JSON, and why you end up moving data between them constantly.
The everyday cases are familiar. An OpenAPI description is written in YAML but the tooling wants JSON. A Kubernetes manifest needs to be inspected as a data structure rather than as text. A CI pipeline file has a subtle nesting bug and seeing it as JSON makes the actual shape unmissable. Or you have a JSON request body that worked in the API tester and you want to check it into a config repository where the house style is YAML and a comment would be genuinely useful.
How the two formats map onto each other
| YAML | JSON | Note |
|---|---|---|
Mapping (key: value) | Object | Keys become strings in JSON |
Sequence (- item) | Array | Order preserved |
| Plain or quoted scalar | String | Quoting decides the type |
42, 3.14 | Number | Unquoted only |
true, false | Boolean | YAML 1.2 rules |
null, ~, empty | null | All three are the same value |
Comment (# …) | — | Lost in conversion; JSON has none |
| Anchor / alias | — | No equivalent; rejected here |
Note the row that has no counterpart. Converting YAML to JSON is lossy in one direction that matters: comments do not survive. If the YAML you are converting is a config file that people maintain, treat the JSON as a view of it rather than as a replacement for it.
An honest statement of what this parser supports
YAML is one of the most complicated text formats in common use. The 1.2 specification runs to more than two hundred production rules, and full compliance means implementing anchors, aliases, tags, multiple documents per stream, explicit typing, merge keys, complex mapping keys, five different scalar styles and a set of indentation rules with genuine corner cases. A converter that claims full compliance and then quietly mishandles one of them is worse than useless, because you will trust the output.
So, plainly: this is a pragmatic subset parser, not a compliant YAML 1.2 implementation.
It handles the constructs that appear in the overwhelming majority of real configuration files —
arbitrarily nested mappings and sequences, mappings inside sequence items, single and double quoted
strings with escape sequences, plain scalars, comments in every position, inline flow collections, literal
and folded block scalars with - and + chomping, and a leading document marker.
Everything else raises an explicit error naming the construct and the line it was found on. Anchors
(&base) and aliases (*base) are rejected because resolving them correctly
requires a full node graph and getting it subtly wrong would duplicate or drop data. Tags such as
!!str or !Ref are rejected because they change how a value is typed, and a
CloudFormation template full of !Ref is not something to guess at. Merge keys, explicit
complex keys and multi-document streams are rejected for the same reason. An error you can read beats a
result you cannot trust, particularly for infrastructure configuration.
The YAML traps worth knowing about
The Norway problem
Under YAML 1.1, the unquoted tokens yes, no, on, off,
y and n are booleans. A list of country codes containing NO for
Norway therefore parses as false, which is where the name comes from. YAML 1.2 narrowed
booleans to true and false, and this converter follows 1.2 — but plenty of
deployed parsers still follow 1.1, so quote anything whose type you care about.
Numbers that were meant to be strings
A version number written as version: 1.10 becomes the number 1.1, losing the trailing zero
forever. A zero-padded value like id: 007 may be read as octal by an older parser. A
MAC-address-like or time-like value can be interpreted as a sexagesimal number. The rule is simple: quote
anything that is an identifier rather than a quantity, even when it looks numeric.
Tabs are illegal in indentation
YAML forbids tab characters in indentation, and because a tab is invisible the resulting error is baffling until you look at the bytes. If a file refuses to parse and the indentation looks right, configure your editor to show whitespace, or paste both versions into the diff checker and compare them with the ignore-whitespace option on and off — a difference that disappears when whitespace is ignored is a whitespace bug.
Duplicate keys
Two identical keys in the same mapping are invalid YAML, but many parsers accept the file and keep the last value. In a long manifest this is easy to do by accident and hard to spot. Converting to JSON and counting the keys is a quick way to catch it, and the JSON formatter will show you the surviving structure.
Indentation of sequences under a key
Both of these are valid and equivalent, which surprises people who assume the second form is wrong: a sequence may be indented under its key, or start at the same column as the key. Neither is more correct, but mixing the two styles in one file makes nesting bugs much easier to introduce.
Frequently asked questions
Will the JSON I get back be byte-identical if I convert it again?
The data will be identical; the text may not. Key order is preserved, but comments are dropped and quoting is normalised. Round-tripping YAML → JSON → YAML gives you equivalent data in a canonical style.
Why does an anchor produce an error rather than being expanded?
Because expanding anchors correctly means building and resolving a node graph, and a partial implementation could duplicate or drop data without telling you. Refusing is the honest answer for a tool you might point at production configuration.
Can I convert a multi-document YAML stream?
Not here — a second --- after content is rejected. JSON has no way to represent several
documents in one text anyway, so split the stream and convert each document separately.
Are comments preserved?
No, and no converter can preserve them: JSON has no comment syntax. Keep the YAML as the source of truth if the comments matter.
Does the converter handle multi-line strings?
Yes. Literal blocks (|) keep newlines, folded blocks (>) join lines with
spaces, and the - and + chomping indicators control the trailing newline.
Related tools and reference
API Tester
Send the JSON you produced here as a request body and see how the API responds.
JSON Formatter
Validate and pretty-print the converted JSON, or sort its keys.
JSON to CSV
Turn a converted list of records into a spreadsheet-ready table.
Diff Checker
Compare two configs after normalising both through JSON.
HTTP Headers
Why Content-Type decides whether a server reads your body as JSON at all.
422 Unprocessable Content
The status an API returns when your document parses but fails validation.