JSON to YAML and YAML to JSON
Convert in either direction and see exactly where YAML quietly changes your data: NO becoming false, 1.10 becoming 1.1, 02134 becoming a number, dates, anchors and merge keys. Choose YAML 1.2 or 1.1 reading rules, get line and column for every syntax error, and nothing leaves your browser.
Load an example
What the parser decided about your values
| Line:col | Text | What happened |
|---|
Runs in your browser with the open-source yaml package (version 2.9.1, ISC licence). Nothing is uploaded or stored. The share link puts your text after the # in the address, which browsers do not send to servers, but anyone you give the link to can read it: do not share configuration that contains secrets.
How to use
- Pick the direction. YAML to JSON reads your YAML with the rules you choose (YAML 1.2 is the current specification; YAML 1.1 is what several older libraries still implement) and writes JSON.
- Read the table What the parser decided about your values. It lists every plain value that was turned into a number, that changed its text on the way, or that a parser of the other YAML version would read differently. Quote those values in your source if the text matters.
- Check the notes above the output: they say when documents were joined into an array, aliases expanded, comments dropped, or infinity written as
null. - For JSON to YAML paste strict JSON. Errors give the line and column. The output is parsed again and compared with your input, and the result of that check is shown under the output.
- Use Use output as input to flip a result back and compare. Use Load an example to see each gotcha on the sample text from this page.
Worked examples
Each block is a real input with the exact compact JSON the tool prints under YAML 1.2 and under YAML 1.1. The expected values were derived by hand from the YAML 1.2.2 core schema table and the yaml.org YAML 1.1 type pages, and a unit test runs every one of them through the converter.
| Core schema pattern (YAML 1.2.2, section 10.3.2) | Read as |
|---|---|
null, Null, NULL, ~, or empty | null |
true, True, TRUE, false, False, FALSE | boolean |
[-+]? [0-9]+ | integer, decimal (so 010 is 10) |
0o [0-7]+ | integer, octal (0o10 is 8) |
0x [0-9a-fA-F]+ | integer, hexadecimal (0x3A is 58) |
[-+]? ( \. [0-9]+ | [0-9]+ ( \. [0-9]* )? ) ( [eE] [-+]? [0-9]+ )? | floating-point number |
.inf, -.Inf, .NaN and spelling variants | infinity, not a number |
| anything else | string |
A quoted scalar ("..." or '...') is always a string, and a tag such as !!str forces the type.
The Norway problem: a country code becomes false
countries: - GB - NO - SE
| Read as | JSON the tool prints |
|---|---|
| YAML 1.2 (default) | {"countries":["GB","NO","SE"]} |
| YAML 1.1 | {"countries":["GB",false,"SE"]} |
The YAML 1.1 boolean type (yaml.org/type/bool) lists y, Y, yes, Yes, YES, n, N, no, No, NO, on, On, ON, off, Off and OFF as booleans, so the unquoted country code NO is false. YAML 1.2 dropped all of these; only true, True, TRUE, false, False and FALSE are booleans. Many tools, and the YAML parsers of several languages, still apply the 1.1 rules, so quote anything that could be read as one: "NO".
The key on becomes true
on:
push:
branches: [main] | Read as | JSON the tool prints |
|---|---|
| YAML 1.2 (default) | {"on":{"push":{"branches":["main"]}}} |
| YAML 1.1 | {"true":{"push":{"branches":["main"]}}} |
The same rule applies to keys, not only values. A YAML 1.1 parser reads the key on as the boolean true, and JSON then has to write it as the member name "true". Anything that reads such a file as YAML 1.1 and looks for a key named on will not find it.
A leading zero: 02134 is 2134 or 1116
zip: 02134
| Read as | JSON the tool prints |
|---|---|
| YAML 1.2 (default) | {"zip":2134} |
| YAML 1.1 | {"zip":1116} |
The YAML 1.2 core schema reads [-+]?[0-9]+ as a decimal integer, so the leading zero is lost and the zip code is the number 2134. YAML 1.1 reads a leading 0 as octal: 2*8^3 + 1*8^2 + 3*8 + 4 = 1024 + 64 + 24 + 4 = 1116. Zip codes, phone numbers and IDs with leading zeros must be quoted. A value such as 08 is not valid octal, so YAML 1.1 falls back to decimal 8 (observed with the yaml package; the 1.1 spec does not describe it).
A version number loses its trailing zero
python: 3.10 node: 20.10
| Read as | JSON the tool prints |
|---|---|
| YAML 1.2 (default) | {"python":3.1,"node":20.1} |
| YAML 1.1 | {"python":3.1,"node":20.1} |
Both versions read 3.10 as a floating-point number (the core schema float pattern is [-+]? ( \. [0-9]+ | [0-9]+ ( \. [0-9]* )? ) ( [eE] [-+]? [0-9]+ )?), and a number carries no trailing zero, so JSON gets 3.1. The text "3.10" and the number 3.1 are different values; a CI matrix that asks for Python 3.10 and gets 3.1 is the classic result. Quote versions: "3.10".
A time such as 12:30 is a number in YAML 1.1
at: 12:30
| Read as | JSON the tool prints |
|---|---|
| YAML 1.2 (default) | {"at":"12:30"} |
| YAML 1.1 | {"at":750} |
YAML 1.1 allows base-60 integers written with colons (yaml.org/type/int: [-+]?[1-9][0-9_]*(:[0-5]?[0-9])+). 12:30 is 12*60 + 30 = 750. YAML 1.2 removed this, so the text stays a string. The same happens to 190:20:30, which is 190*3600 + 20*60 + 30 = 685230.
A date is text in YAML 1.2 and a timestamp in YAML 1.1
released: 2001-12-14
| Read as | JSON the tool prints |
|---|---|
| YAML 1.2 (default) | {"released":"2001-12-14"} |
| YAML 1.1 | {"released":"2001-12-14T00:00:00.000Z"} |
The YAML 1.1 timestamp type (yaml.org/type/timestamp) treats a plain date as a timestamp at 00:00:00 UTC. JSON has no date type, so this tool writes the ISO 8601 string. A parser that builds real date objects will hand your code a Date, not the text you wrote.
An empty value is null, not an empty string
name: nickname: ~ motto: ""
| Read as | JSON the tool prints |
|---|---|
| YAML 1.2 (default) | {"name":null,"nickname":null,"motto":""} |
| YAML 1.1 | {"name":null,"nickname":null,"motto":""} |
The core schema resolves an empty plain scalar, ~, null, Null and NULL to null. Only the pair of quotes gives an empty string. A config key left blank is therefore null.
The merge key << merges only under YAML 1.1 rules
base: &b {x: 1}
d:
<<: *b
y: 2 | Read as | JSON the tool prints |
|---|---|
| YAML 1.2 (default) | {"base":{"x":1},"d":{"<<":{"x":1},"y":2}} |
| YAML 1.1 | {"base":{"x":1},"d":{"x":1,"true":2}} |
The merge key is defined on yaml.org/type/merge for YAML 1.1 and does not appear in the YAML 1.2.2 specification. With the default settings here << is an ordinary key, so nothing is merged (many libraries merge it anyway; behaviour varies). Tick "Treat << as a merge key" to merge. The 1.1 result above also shows the key y turning into "true": the two gotchas combine.
Several documents in one file
name: first --- name: second --- - third
Output: [{"name":"first"},{"name":"second"},["third"]], with the note that JSON has no multi-document form.
What goes wrong
Syntax errors a converter should explain rather than guess around. The messages are the parser's own; the tool adds the line and column and shows the offending line.
A tab used as indentation
a: <TAB>b: 1
Error: Line 2, column 1: Tabs are not allowed as indentation
YAML 1.2.2 section 6.1 says tab characters must not be used in indentation. Editors that insert tabs are the usual cause; use spaces.
Duplicate keys
a: 1 a: 2
Error: Line 2, column 1: Map keys must be unique
YAML requires the keys of a mapping to be unique (YAML 1.2.2 section 3.2.1.1). Many parsers silently keep the last value; this one stops and tells you where. JSON is different: RFC 8259 calls duplicate names "unpredictable".
An unclosed flow list
server: host: example.com ports: [80, 443 tls: true
Error: Line 4, column 3: Flow sequence in block collection must be sufficiently indented and end with a ]
The position is where the parser gave up: it was still looking for the closing bracket when the next line (tls: true, line 4) began. It is not where the list started, and the real mistake is on the line above the reported one.
Alias without an anchor
a: &x 1 b: *x c: *y
Error: Line 3, column 4: The alias *y has no anchor. An anchor (&y) must be written earlier in the same document.
YAML 1.2.2 section 3.3.1 requires each alias to refer to a previous node identified by the anchor, and says a processor should reject unidentified aliases.
Keys that JSON cannot hold
1: a "1": b
Error: Two mapping keys both become the JSON member name "1" (for example 1 and "1"). JSON would then have a duplicate name, so the conversion stops.
YAML keys can be numbers, booleans, null or even whole lists; JSON member names are strings. A key that is a list or map cannot be converted at all, and the tool says so.
Trailing comma in JSON
{
"a": 1,
} Error (JSON to YAML): Line 3, column 1: Trailing comma before "}", with the hint "JSON does not allow a comma after the last member." JSON (RFC 8259) does not allow a trailing comma, comments or single quotes, although YAML does allow comments.
Limits & gotchas
- The behaviour for YAML 1.1 is that of one library, not the specification. The yaml package implements 1.1 as an option. The booleans, octal, hexadecimal, binary, underscores, base-60 integers and timestamps shown here match the yaml.org 1.1 type pages in the cases tested; where those pages are silent (for example
08, which is not valid octal) the tool reports what the library does and says so. Other libraries differ, which is the point of the gotchas above. - The 1.2 default is the core schema. The YAML 1.2.2 specification recommends the core schema as the default for processors, and that is what "YAML 1.2" means here. Other schemas (failsafe, JSON) and custom tags are not offered. Unknown tags are ignored with the value kept as text;
!!binaryis written as Base64 and timestamps as ISO 8601 strings. - Merge keys.
<<is merged only when you tick the option or choose YAML 1.1. The YAML 1.2.2 text does not define it, and libraries disagree on whether to merge by default. - A %YAML directive in your text wins. If a document starts with
%YAML 1.1, the library reads it as 1.1 whatever the selector says; the tool prints a note when it sees one. This was observed, not taken from a specification. - Comments, anchors and formatting are not round-tripped. Output is regenerated, so comments, anchor names, quoting style and blank lines from the source are not preserved. Long lines are not folded.
- Numbers. Integers beyond 253-1 are written exactly in the JSON, but JavaScript's
JSON.parsewill round them when your code reads the file. Infinity and NaN cannot be written in JSON and becomenull, with a note. - Mapping key order for whole-number keys in JSON to YAML follows JavaScript object order (integer-like names first, ascending), because the JSON is read into a JavaScript object. The tool says when this applies.
- Size. No hard limit; the page converts on every pause in typing, so very large documents (many megabytes) will feel slow. The alias limit of 100 stops expansion bombs.
- Share links carry your text in the part after
#, up to about 3,000 characters. Never share configuration that contains passwords, tokens or keys.
Library: the yaml npm package by Eemeli Aro, version 2.9.1, ISC licence (a permissive licence); the licence and version were read from the package metadata installed with this site.
FAQ
Why did NO (or no, yes, on, off) turn into a boolean?
Because the parser follows YAML 1.1, whose boolean type includes y, Y, yes, Yes, YES, n, N, no, No, NO, on, On, ON, off, Off and OFF (yaml.org/type/bool). YAML 1.2.2 (core schema) only treats true, True, TRUE, false, False and FALSE as booleans, so under 1.2 the country code NO is the string "NO". Which one you get depends on the library. If a value must stay text, quote it, and use the "Read YAML as" selector above to see both results.
Does the converter keep comments, anchors and key order?
Key order is kept for YAML to JSON. Comments are not part of the data and are dropped; the tool tells you when it drops any. Anchors and aliases are expanded into full copies, because JSON has no references, and the output says how many it expanded. JSON to YAML cannot recreate anchors or comments that the JSON never had. One exception to key order: JSON member names that are whole numbers (such as "2") are listed first in ascending order, because JavaScript objects order them that way, and the tool says so when it happens.
What happens to a file with several documents separated by ---?
YAML allows many documents in one stream (YAML 1.2.2 chapter 9); JSON does not. The converter writes the documents as one JSON array, in order, and says so. A file with a single document is not wrapped. If you need one JSON file per document, split the stream at the --- lines first.
Is the converter safe for huge or hostile YAML?
It runs in your tab, so nothing reaches a server, but a malicious document can still try to use your memory. The parser stops after its alias limit (maxAliasCount 100 in the yaml package) to defeat "billion laughs" documents that expand exponentially, and the tool reports it as an error. There is no other size limit besides the memory of your browser, and very large inputs make typing slow.
Will JSON converted to YAML read back identically?
The tool checks this for you: after writing YAML it parses the result again and compares it with your JSON, and shows a warning if they differ. Strings that would otherwise be read as another type (true, null, 010, 1.10, ~, an empty string, text containing ": ") are quoted. Words such as NO, y or 12:30 are only quoted if you tick the YAML 1.1 option, because under YAML 1.2 they are plain strings. Numbers beyond 2^53 are written exactly, but JavaScript's JSON.parse rounds them when reading.
Sources
- yaml.org: YAML Ain't Markup Language (YAML) revision 1.2.2 Used for: Core schema (booleans true/false only, null, ints, floats), anchors and aliases, multiple documents, tabs not allowed for indentation, JSON as a subset.
- yaml.org: Boolean Language-Independent Type for YAML Version 1.1 Used for: YAML 1.1 booleans: y, Y, yes, Yes, YES, n, N, no, No, NO, true, True, TRUE, false, False, FALSE, on, On, ON, off, Off, OFF.
- yaml.org: Integer Language-Independent Type for YAML Version 1.1 Used for: YAML 1.1 integers: leading 0 means octal, 0x hexadecimal, 0b binary, underscores ignored, colons mean base 60 (190:20:30 = 685230).
- yaml.org: Timestamp Language-Independent Type for YAML Version 1.1 Used for: YAML 1.1 timestamps: a plain date is a timestamp; an omitted time zone means UTC and an omitted time means 00:00:00Z.
- yaml.org: Merge Key Language-Independent Type for YAML Version 1.1 Used for: The "<<" merge key is a YAML 1.1 type that is not in the 1.2 core schema.
- IETF: RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format Used for: JSON grammar: no comments, no trailing commas, double-quoted strings, number syntax; duplicate names are "unpredictable".
- Ecma International (TC39): ECMAScript Language Specification: OrdinaryOwnPropertyKeys Used for: Integer-index property names are listed first in ascending numeric order, then string keys in creation order.
- Eemeli Aro: "yaml" npm package, version 2.9.1 (ISC licence) Used for: The parser and stringifier this page runs in your browser. Default YAML 1.2 core schema; options version "1.1", maxAliasCount, uniqueKeys; errors carry line and column; ISC licence from the package metadata (npm view yaml license).
Every document above was opened and read on 2026-10-02. Documentation changes; if a page here disagrees with the current docs, trust the docs and tell us.