Skip to content
AgileLogics

YAML to JSON

Parses a YAML document (including merge keys and multi-document streams) and converts it into equivalent, pretty-printed JSON.

Working on a whole file? Open it in the YAML editor →

How it works

Paste YAML into the input panel and click Convert.

What happens when YAML becomes JSON?

Converting YAML to JSON means parsing the YAML into plain data (mappings, sequences and scalars) and writing that data out in JSON syntax. Comments, anchors and formatting choices disappear, and every unquoted value has to be resolved to a type. Those type rules decide whether 1.10 stays a version string or becomes the number 1.1.

The converter uses the js-yaml library (version 5.4.2) with its default schema, the YAML 1.2 core schema described in the YAML 1.2.2 specification. The JSON is printed with two-space indentation.

A worked example

service: checkout
replicas: 3
enabled: yes
image: &img
  registry: ghcr.io
  tag: "1.4"
sidecar:
  image: *img
ports:
  - 8080
  - 8443
notes: |
  Deployed by CI.

becomes:

{
  "service": "checkout",
  "replicas": 3,
  "enabled": "yes",
  "image": {
    "registry": "ghcr.io",
    "tag": "1.4"
  },
  "sidecar": {
    "image": {
      "registry": "ghcr.io",
      "tag": "1.4"
    }
  },
  "ports": [
    8080,
    8443
  ],
  "notes": "Deployed by CI.\n"
}

The alias *img was expanded into a second copy of the image block. enabled: yes stayed a string, because YAML 1.2 doesn't treat yes as a boolean. The literal block (|) kept its trailing newline.

How unquoted values are typed

These results come straight from the converter:

YAML JSON Why
country: NO "NO" Only true/false are booleans in YAML 1.2
version: 1.10 1.1 Looks like a float, so trailing zeros go
quoted: "1.10" "1.10" Quotes always force a string
zip: 01234 1234 Leading zeros are ignored for decimal integers
octal: 0o14 12 0o is the 1.2 octal prefix
hex: 0x1F 31 Hexadecimal integer
date: 2026-10-27 "2026-10-27" No timestamp type in the core schema
nothing: ~ and empty: null Both are null
inf: .inf null JSON has no Infinity, so it prints null
url: http://x.com:8080/a "http://x.com:8080/a" A colon not followed by a space is just text

The safe habit is to quote anything that must stay a string: version numbers, postcodes, IDs with leading zeros, phone numbers. Integers longer than 15 or 16 digits also lose precision, since they're stored as JavaScript numbers.

Things that stop the conversion

The error message includes a line and column plus a small excerpt with a caret under the problem. The usual causes:

  1. Unclosed brackets or quotes. b: [1, 2 fails with "unexpected end of the stream within a flow collection".
  2. Tabs in indentation. YAML forbids them; the error is "tab characters must not be used in indentation".
  3. Custom tags. CloudFormation's !Ref or !GetAtt, and also !!binary and !!set, fail with "unknown scalar tag" or "unknown mapping tag".
  4. Duplicate keys. Two a: keys in one mapping give "duplicated mapping key".
  5. Complex keys. A sequence used as a key (? [a, b]) can't become a JSON property name.

Two inputs that other tools reject do convert here. A stream of several ----separated documents becomes a JSON array with one item per document, and a file containing only comments converts to null, because it holds no data.

If you only want to know whether a file parses, the YAML validator runs the same parser without producing output.

Merge keys are applied

Many configuration files share settings with a merge key, like this:

defaults: &defaults
  adapter: postgres
  port: 5432
development:
  <<: *defaults
  database: app_dev
  port: 5433

That merge key belongs to YAML 1.1's type repository, not to the 1.2 core schema, but the converter enables it because so many real files depend on it. The anchored keys are copied into development, and a key written in the mapping itself wins over the merged one, so port is 5433:

"development": {
  "adapter": "postgres",
  "port": 5433,
  "database": "app_dev"
}

A list of aliases (<<: [*base, *extra]) merges several mappings, with earlier ones taking precedence. To keep a literal << key instead, quote it: "<<": value.

Multi-line strings

YAML has two block styles for long text, and they convert differently. Take two indented lines, "word one" and "word two". Under a literal block (|) every line break is kept, giving "word one\nword two\n". Under a folded block (>) the lines are joined with a space, giving "word one word two\n": one line with a single newline at the end. Both styles keep one trailing newline by default. Add a chomping indicator (|- or >-) to drop it, or |+ to keep every trailing blank line. If a JSON consumer compares strings exactly, that final \n is a common source of "the values look identical but don't match" bugs.

Key order is preserved: properties appear in the JSON in the same order as in the YAML, which makes it easy to compare the two side by side.

After converting

YAML 1.2 was designed so that JSON documents are also valid YAML, which means you can paste JSON into this tool and get it back reformatted. More often the next step goes the other way: tidy the result with the JSON formatter, or query parts of it with the JSONPath tester. For editing YAML with syntax highlighting, use the online YAML editor.

Last updated

Frequently asked questions

Why did yes, no, on and off stay as strings?
The converter follows the YAML 1.2 core schema, where only true and false (written as true, True or TRUE) are booleans. In older YAML 1.1 parsers, yes/no/on/off were booleans too, which is why country: NO used to turn into false. Here it stays "NO".
Are anchors and aliases supported?
Yes. An alias such as *img is replaced with a full copy of the anchored value, so the JSON repeats the data wherever the alias appeared. JSON has no way to express a reference.
Are merge keys (<<: *defaults) applied?
Yes. Merge keys come from YAML 1.1 rather than the 1.2 core schema, but they're so common in Docker Compose, CI and Rails files that the converter enables them. The anchored keys are copied into the mapping, and keys written in the mapping itself take precedence.
Can I convert a file with several documents separated by ---?
Yes. A stream with more than one document becomes a JSON array with one item per document, in order. A single document, with or without a leading ---, converts to that document on its own.
What do I get for a file that only has comments?
null. A YAML stream with no documents holds no data, which JSON writes as null.
Is my YAML uploaded?
No. Parsing is done by the js-yaml library running in your browser, and nothing is sent to a server.