HandyBench

JSON ⇄ YAML Converter

Convert between JSON and YAML both ways.

How to use the JSON ⇄ YAML Converter

  1. 1 Choose JSON → YAML or YAML → JSON.
  2. 2 Paste your JSON or YAML into the box. YAML may use anchors, aliases and merge keys.
  3. 3 Click Convert and copy the formatted result.

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

FeatureHow it converts
Nested maps and - sequences, including - - x on one lineObjects 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 scalarsLine breaks fold into single spaces, and a blank line becomes a line break
Block scalars | and >, with chomping (|-, |+, >-) and indentation indicatorsStrings, as described below
Flow lists and maps such as [a, b] and {a: 1, b: [x, y]}, including over several linesArrays 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 filesComments 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-01Stay 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 as don't is just text, so a # comment after it is still recognised.
  • 007 becomes the number 7, and yes stays the string "yes".

Tidy JSON first with the JSON formatter, or move tabular data with JSON to CSV and JSON to XML.

Examples

  • ▸ Turning a config JSON into readable YAML.
  • ▸ Converting a YAML file back to JSON for an API.
  • ▸ Expanding a docker-compose or CI file that reuses blocks with &anchors and <<: *merge keys.

Frequently asked questions

Is my data uploaded anywhere?

No. The conversion runs entirely in your browser, so configuration data and secrets in your files never leave your device.

Which YAML features are supported?

YAML to JSON reads full YAML 1.2: maps, sequences, nesting, flow lists and maps, block scalars (| and >, with - and + chomping), multi-line plain and quoted text, anchors (&name) with aliases (*name), merge keys (<<), tags like !!str, and multi-document files. JSON to YAML writes plain maps, lists and scalars, so it never produces anchors.

Why are some strings quoted in the YAML output?

Strings that could be misread are double-quoted: words like yes, no and null, values that look like numbers or dates ("1.0", "2024-01-01"), empty strings, anything with leading or trailing spaces, a colon, a hash or a line break, and anything starting with a symbol such as a slash. Plain words are left bare.

What happens with a file that has several YAML documents?

Documents separated by --- are returned as a JSON array with one entry per document, and a note above the result says how many were found. A file with a single document converts to that document itself, not to an array.

What happens if my YAML has a mistake or an unknown tag?

Invalid YAML stops with an error naming the line instead of returning a result with data missing, for example a tab used as indentation, an unclosed [ or an alias whose anchor was never defined (the line of the alias is named). When the parser cannot place a mistake, the message names the document instead. A key that appears twice in one mapping is also an error rather than one value silently overwriting the other. Unknown tags such as !Ref are read as plain text, and !!set, !!omap and !!binary become arrays and base64 text, each with a note under the result.

Is every JSON file already valid YAML?

In YAML 1.2 essentially yes, since YAML was designed as a superset of JSON. The reverse is not true, because YAML allows comments, indentation-based nesting and unquoted values that JSON forbids.