# YAML to JSON Converter

Convert YAML to JSON and back without uploading anything — and see, line by line, every value a YAML 1.1 parser would read differently from a YAML 1.2 one.

- Runs in your browser
- Nothing uploaded
- YAML 1.1 and 1.2
- Line-numbered warnings

## Quick answer

YAML 1.1 reads `NO` and `yes` as booleans, so `country: NO` becomes `{"country":false,"enabled":true}`; under YAML 1.2's core schema the same text becomes `{"country":"NO","enabled":"yes"}`. The converter shows which reading it used and warns on every value where the two versions disagree.

## About the YAML to JSON Converter

This converter turns YAML into JSON and JSON into YAML entirely in your browser, and it tells you where the conversion could change your data. Two versions of YAML are in everyday use. Version 1.2 is the current specification; version 1.1 is older, but it is still what PyYAML, Ruby's built-in YAML module and many other parsers follow. The two disagree about unquoted values such as `NO`, `off`, `0755` and `1:20`, so the same file can load as different data depending on which program reads it.

When you convert YAML to JSON, the tool reads every unquoted value under both versions and lists each one that comes out differently, with its line number, what ended up in the JSON and what the other version would give. It also reports what JSON has no room for: comments, anchors and aliases, merge keys, custom tags and keys that are not strings. Going the other way, it writes YAML that quotes every string a YAML 1.1 parser would misread or refuse, so old and new parsers load the same values.

## How to use it

Choose the direction. For **YAML → JSON**, paste your YAML into the box; several documents separated by `---` are fine. Leave **Read with** on YAML 1.2 unless the file is consumed by a YAML 1.1 parser and you want the JSON that parser would produce. For **JSON → YAML**, paste strict JSON. The output updates as you type, and **Indent** switches between two and four spaces.

Under the output, the table lists every value worth a second look, ordered by line: the text as written, what ended up in the output, and why it matters. The notes below it cover the structural changes — documents combined into an array, comments dropped, aliases expanded — followed by one line of advice for each kind of problem found. **Show the math** lists each stage of the conversion with counts. If the input has a syntax error, the message gives the line and column of the first problem. **Copy** puts the output on your clipboard.

## Use cases

- **Feeding a config file to a JSON-only tool.** Turn a Kubernetes manifest, a CI workflow or an application's settings file into JSON for jq, a REST API or a test fixture, and see in the same step whether any value would change meaning.
- **Auditing a file before switching parsers.** Moving a service from a YAML 1.1 library to a 1.2 one, or the other way round? Read the file under each version and quote every flagged line before the switch.
- **Tracking down a "false" nobody wrote.** A country code of NO, a feature switch called off, a Python version of 3.10 that became 3.1 — the warnings point at the exact line.
- **Writing YAML from generated JSON.** API responses and generated objects come out as YAML with quotes exactly where an older parser would otherwise misread a value, and nowhere else.
- **Validating YAML against a schema.** Convert to JSON here, then check the result with the [JSON Schema validator](https://17x7.com/tools/json-schema-validator/), or draft a schema from it with the [JSON Schema generator](https://17x7.com/tools/json-schema-generator/).
- **Reading schedules in CI files.** Workflow and CronJob files often carry cron strings; paste one into the [cron expression explainer](https://17x7.com/tools/cron-expression/) to read it in plain English.

## How the conversion works

The converter is built on the open-source `yaml` library for JavaScript. Reading YAML happens in two stages: the parser first finds the structure — mappings, sequences and scalars — and then gives each unquoted scalar a type by matching it against the patterns of a schema. Quoted scalars are always strings, so they never cause trouble. Unquoted (plain) scalars are where the versions part ways, because YAML 1.1 and the YAML 1.2 core schema use different patterns. This tool parses your text once under each version, lines the two results up by their position in the file, and compares every plain scalar. Each one that resolves differently becomes a row in the warnings table.

The JSON writer is part of this tool rather than the browser's built-in one, because the built-in writer loses information. This one keeps mapping keys in the order you wrote them (a plain JavaScript object would move a key like `"2"` ahead of `"b"`), writes integers larger than 2^53 digit for digit, turns YAML 1.1 timestamps into ISO 8601 strings, and writes `.inf` and `.nan` as `null`, since JSON has no way to spell them.

## YAML 1.1 vs YAML 1.2: one file, two meanings

YAML 1.1, published in 2005, tried hard to guess types. Twenty-two spellings counted as booleans — y, yes, on and true for true; n, no, off and false for false, each in lower, capitalized and upper case. A leading zero meant octal, digits separated by colons meant base 60 (so a duration could be written as 1:20), underscores could group digits, and anything shaped like a date became a timestamp. YAML 1.2, published in 2009, dropped nearly all of that so that its core schema would line up with JSON: only true and false are booleans, octal needs a `0o` prefix, and colons, underscores and dates stay as text.

The best-known casualty is the "Norway problem": in a list of country codes, NO — Norway — loads as false. The table below was produced by this converter: each value written without quotes, read under each version and shown as JSON.

| Written    | Typically             | YAML 1.2 reads | YAML 1.1 reads             |
| ---------- | --------------------- | -------------- | -------------------------- |
| NO         | Norway's country code | "NO"           | false                      |
| yes        | an answer             | "yes"          | true                       |
| off        | a switch name         | "off"          | false                      |
| y          | a single letter       | "y"            | true                       |
| 0755       | a file mode           | 755            | 493                        |
| 08         | a month               | 8              | 8                          |
| 1:20       | a duration            | "1:20"         | 80                         |
| 2222:22    | a port mapping        | "2222:22"      | 133342                     |
| 1\_000     | a grouped number      | "1\_000"       | 1000                       |
| 0b101      | a binary literal      | "0b101"        | 5                          |
| 0o17       | a 1.2 octal literal   | 15             | "0o17"                     |
| 2026-10-08 | a date                | "2026-10-08"   | "2026-10-08T00:00:00.000Z" |
| 3.10       | a version number      | 3.1            | 3.1                        |

Two rows deserve a closer look. A leading zero is lost under both versions — `0755` reads as 755 under 1.2 and 493 under 1.1 — so neither gives back the digits you typed. And `3.10` is a number in both, which is how a Python version of 3.10 in a CI matrix quietly becomes 3.1\. The converter flags these even when the versions agree, because the fix is the same: put the value in quotes.

## Worked example

Five lines from a deployment file:

```
country: NO
python: 3.10
umask: 0022
ports:
  - 2222:22

```

Read with YAML 1.2, the JSON is:

```
{
  "country": "NO",
  "python": 3.1,
  "umask": 22,
  "ports": [
    "2222:22"
  ]
}
```

Read with YAML 1.1, the same lines give:

```
{
  "country": false,
  "python": 3.1,
  "umask": 18,
  "ports": [
    133342
  ]
}
```

Under the default YAML 1.2 setting the converter reports 4 warnings for this snippet:

- Line 1: `NO` — YAML 1.1 reads false.
- Line 2: `3.10` — trailing zero lost.
- Line 3: `0022` — YAML 1.1 reads 18.
- Line 5: `2222:22` — YAML 1.1 reads 133342.

Quoting those values — `"NO"`, `"3.10"`, `"0022"` and `"2222:22"` — makes both versions return the same strings.

## What a round trip loses

JSON is a much smaller language than YAML, so converting YAML to JSON and back never returns your original file. Here is what goes missing, and what the notes under the result tell you about each:

- **Comments.** JSON has no comment syntax, so every comment is dropped. The notes list the lines they were on, so you know what to carry over by hand.
- **Anchors and aliases.** An anchor such as `&defaults` and each alias `*defaults` become separate full copies. The data is the same, but editing one copy no longer changes the others, and a heavily aliased file can grow considerably.
- **Merge keys.** A `<<` key copies another mapping's keys into the current one, and keys written alongside it win. The converter applies the merge, as most tools do, but merge keys were never part of the YAML 1.2 core schema, so each one is noted.
- **Tags.** Custom tags such as `!Ref` or `!Sub` have no JSON form. The tag is dropped and the value is kept as plain data.
- **Key types.** YAML allows numbers, booleans, null and even lists as mapping keys. JSON keys are always strings, so `200` becomes `"200"`, and two keys that end up with the same text collapse into one.
- **Spelling of numbers.** JSON stores values, not the way you wrote them: `0x1F` comes back as 31 and `1.50` as 1.5.
- **Layout.** Key order survives in both directions here, but flow versus block style, blank lines and quoting style do not; YAML output always uses block style.

## JSON to YAML: quotes that keep old parsers honest

A YAML writer that follows only version 1.2 prints the string "off" without quotes, because under 1.2 it is an ordinary string. Load that file with a YAML 1.1 parser and the string turns into false. So when converting JSON to YAML, this tool also tests every string against the YAML 1.1 patterns and quotes the ones that would be misread — and only those, so the output stays easy to read. This JSON:

```
{"country": "NO", "on": "push", "mode": "0644", "python": "3.10", "ports": ["8080:80", "2222:22"]}
```

becomes:

```
country: "NO"
"on": push
mode: "0644"
python: "3.10"
ports:
  - 8080:80
  - "2222:22"

```

`"NO"`, `"on"` and `"2222:22"` are quoted for the sake of YAML 1.1 parsers. `"0644"` and `"3.10"` are quoted because even YAML 1.2 would read them as numbers, while `8080:80` is safe without quotes under both versions.

A few strings are quoted not because a 1.1 parser would misread them but because it would stop with an error. A lone `=` is YAML 1.1's special "value" key and `<<` is its merge key, wherever they appear, so a filter rule such as `{"op": "="}` written plainly cannot be loaded by PyYAML. The same goes for a string containing a tab, which 1.1 parsers do not accept in unquoted text, and for the characters U+0085, U+2028 and U+2029, which YAML 1.1 counts as line breaks; those are written as the escapes `\N`, `\L` and `\P`. Numbers get the same care: JSON's 1e-7 and 1e21 are written 1.0e-7 and 1.0e+21, a spelling with a decimal point and a signed exponent that YAML 1.2 and YAML 1.1 parsers both read as a float.

Some characters cannot appear raw in YAML of either version, quoted or not: DEL, the C1 control codes from U+0080 to U+009F other than U+0085, and U+FFFE and U+FFFF. They usually arrive in text that was decoded with the wrong character set. In `{"title": "Don\u0092t stop"}`, U+0092 is what is left of a typographic apostrophe from a Windows code page, and the converter writes it as `title: "Don\x92t stop"`, an escape that every parser reads back as the same character. One more case concerns layout rather than characters. A string nested inside a mapping or list that spans lines is written as an indented block, but when the whole JSON value is one such string, as in `"first line\nsecond line"`, the block would start in the first column, and PyYAML refuses that. The converter keeps such a string on one line in double quotes instead, as `"first line\nsecond line"`, with each line break written as `\n`.

The JSON reader is strict, as the JSON standard (RFC 8259) requires: double-quoted strings and keys, no comments, no trailing commas, no NaN. Errors give a line and column and, for the common mistakes, say what to change. Duplicate keys, which many JSON readers tolerate but YAML forbids, are resolved the way JavaScript's JSON.parse resolves them — the last value wins — and the note shows both lines. Integers too large for a JavaScript number are copied digit for digit instead of being rounded, and a float such as 1.0 stays 1.0 rather than becoming the integer 1.

## Privacy

The conversion runs in this page's JavaScript. Nothing you paste is uploaded, stored or logged, and the text never goes into the address bar: **Copy link** saves only the direction, indent and version settings. To check, open your browser's developer tools, switch to the Network panel and convert something — no request is sent. Once the page has loaded, conversion works with the network switched off.

## Limits

- Inputs over 1,000,000 characters are refused. Everything runs on the page itself, so a file close to that size can take a few seconds.
- YAML 1.1 handling follows the YAML 1.1 schema of the underlying library. Real parsers differ at the edges: PyYAML, for example, reads y and n as strings, and reads 1e3 as a string as well.
- Custom tags are dropped, not translated: `!Ref` in an infrastructure template does not become the equivalent JSON function syntax.
- Expanding aliases may add at most 250,000 values to the data. A file built to explode when its aliases are copied (an "alias bomb") is refused with the line of the alias responsible, instead of freezing the browser. Ordinary files with thousands of aliases are fine.
- YAML indented past about column 256, or nested more than about 256 levels deep, is refused, with the line and column where the limit is passed. The check counts columns, so a file indented four spaces per level is accepted to about 64 levels. JSON nested more than 256 levels deep is refused too, and so is an alias whose copy would reach that deep once expanded, counting each merge key it passes through as a level.
- The YAML output never folds long lines; long strings stay on one line.

## Sources

- [YAML Ain't Markup Language version 1.2.2 — specification](https://yaml.org/spec/1.2.2/) — checked 2026-10-10
- [YAML 1.1 — Boolean language-independent type](https://yaml.org/type/bool.html) — checked 2026-10-10

## Frequently asked questions

Why did NO turn into false?

Under YAML 1.1 rules NO is one of the spellings of false, along with no, n, off and their capitalized forms. YAML 1.2 dropped those, but parsers that follow 1.1 still apply them. Write "NO" in quotes and every parser reads a string. Set Read with to YAML 1.1 to see the JSON such a parser would produce.

Which YAML version should I choose?

The version your consuming program uses. If you are not sure, leave YAML 1.2 selected and read the warnings: every value listed is one where the choice changes the result. Quote those values and the question stops mattering.

Why is my JSON an array?

Your input contains more than one YAML document, separated by lines of three dashes. JSON holds a single value, so the documents become the elements of an array, in order, and an empty document becomes null. Convert one document at a time if you need separate files.

Why does the YAML output quote some strings and not others?

Strings are quoted only when an unquoted copy would be read as something else (a boolean, a number, a date, null, a merge key or the = value key) or would stop a YAML 1.1 parser, as a tab or a stray control character does. Some of those ("true", "42") would be misread by any YAML parser; others ("yes", "1:20", "=") only by YAML 1.1 parsers. Everything else is written plain so the file stays readable.

Does it handle anchors, aliases and merge keys?

Yes. Aliases are replaced by full copies of what they point to, merge keys are applied with the mapping's own keys taking priority, and the notes list each one by line. An alias with no anchor before it, or a merge key pointing at something other than a mapping, is reported with its line and column. Converting back to YAML will not restore the anchors, because JSON has no way to record that two values were the same object.

Can I get my comments back after a round trip?

No. JSON has no place to keep comments, so they are gone the moment the file becomes JSON. Keep the YAML as the file you edit and treat the JSON as a generated copy; the notes list which lines held comments.

Is my YAML or JSON sent anywhere?

No. Parsing and conversion happen in your browser, the pasted text is not stored, and it is left out of the address when you copy a link. The browser's Network panel shows no request when you convert.

**Disclaimer.** Results follow the YAML 1.2 and YAML 1.1 schemas as implemented by the open-source yaml library; individual parsers can differ at the edges, so test files that matter with the program that will read them.

Last updated October 11, 2026. Found a mistake? [Tell us](https://17x7.com/contact/) — corrections ship the same week.

---

Source: https://17x7.com/tools/yaml-to-json/ · Last updated: 2026-10-11
