How YAML to JSON Converter works
This YAML to JSON converter reads block-style YAML (nested maps, lists, lists of maps, inline [a, b] and {k: v} collections, comments and simple | and > text blocks) and writes JSON indented by 2 or 4 spaces. Set Direction to JSON → YAML to go the other way. Types follow the older YAML 1.1 habit for words: unquoted yes, no, on and off in any letter case become true or false, so the country code NO turns into false unless it is quoted. Numbers are stricter: 0755, 01234 and 1.2.3 stay strings. It handles a common subset of YAML, not the whole specification; anchors, multi-document files and a few other features are listed further down.
How unquoted YAML values convert to JSON
Every row is the real output of this tool for a value written without quotes after a key.
| YAML value | JSON output | Why |
|---|---|---|
| NO, no, off, False | false | Boolean words are matched in any letter case |
| yes, On, True, TRUE | true | Same rule |
| y, n | "y", "n" | Single letters are not treated as booleans |
| ~, null, Null, NULL, or nothing after the colon | null | All mean no value |
| 42, -7, 3.14 | 42, -7, 3.14 | Canonical integers and decimals become numbers |
| 1.20 | 1.2 | Read as a number, so the trailing zero is lost |
| 3.0 | 3 | Same: a version written 3.0 needs quotes |
| 1e5 | 100000 | Exponent notation is a number |
| 0755, 01234, 007 | "0755", "01234", "007" | A leading zero keeps the value a string |
| 1.2.3 | "1.2.3" | Two dots is not a number |
| 500m, 512Mi | "500m", "512Mi" | A unit suffix keeps it a string |
| 0x1F, 0o14, 1_000 | "0x1F", "0o14", "1_000" | Hex, octal and underscore forms are not converted |
| .5, +1, 1. | ".5", "+1", "1." | A number needs a digit before and after the dot, and no plus sign |
| 2024-01-15, 09:30 | "2024-01-15", "09:30" | Dates and times are always strings |
| 9007199254740993 | 9007199254740992 | Too large to hold exactly as a JavaScript number |
| "no", 'yes', "0755" | "no", "yes", "0755" | Anything in quotes is a string |
Keys follow the same rules. The GitHub Actions key on: is read as a boolean and comes out as the JSON key "true"; write "on": to keep it.
YAML to JSON examples
JSON is shown on one line to save space; the tool prints it indented.
Nested map with lists (the default sample)
name: web-api / replicas: 3 / enabled: true / resources: with cpu: 500m and memory: 512Mi nested under it / ports: with - 8080 and - 8443 / tags: with - production and - eu-west
{"name":"web-api","replicas":3,"enabled":true,"resources":{"cpu":"500m","memory":"512Mi"},"ports":[8080,8443],"tags":["production","eu-west"]}
The # Deployment settings comment on the first line is dropped.
List of maps, as in CI steps
steps: / - name: Checkout / uses: actions/checkout@v4 / - name: Test / run: npm test / with: / node: 20
{"steps":[{"name":"Checkout","uses":"actions/checkout@v4"},{"name":"Test","run":"npm test","with":{"node":20}}]}
Inline (flow) collections
ports: [80, 443] / env: {NODE_ENV: production, DEBUG: false}
{"ports":[80,443],"env":{"NODE_ENV":"production","DEBUG":false}}
Country codes, one quoted and one not
countries: / - GB / - NO / - SE / - "NO"
{"countries":["GB",false,"SE","NO"]}
Literal and folded text blocks
script: | followed by the lines echo one and echo two / desc: > followed by the lines folded text and on two lines
{"script":"echo one\necho two","desc":"folded text on two lines"}
No trailing newline is added to either value.
Docker Compose port mappings
ports: / - "8080:80" / - 8443:443
{"ports":["8080:80","8443:443"]}
A colon only separates key and value when a space or the end of the line follows it.
JSON to YAML: which strings get quotes
Going from JSON to YAML, a string is quoted only when this tool would otherwise read it back as a different type or as YAML syntax.
| JSON string | YAML output | Reason |
|---|---|---|
| "web-api" | web-api | Plain text needs no quotes |
| "https://example.com" | https://example.com | A colon without a following space is safe |
| "NO", "yes", "Off", "true" | "NO", "yes", "Off", "true" | Would be read as booleans |
| "null", "~" | "null", "~" | Would be read as null |
| "3", "1.20", "1e5" | "3", "1.20", "1e5" | Would be read as numbers |
| "" | "" | An empty value would be read as null |
| "key: value" | "key: value" | Colon followed by a space |
| "a #b" | "a #b" | Space followed by # starts a comment |
| "*.js", "@scope/pkg", "[1]", "!important" | Quoted | Starts with a character YAML reserves |
| "line1\nline2" | "line1\nline2" | Kept on one line with an escaped newline, not as a | block |
| "1.2.3", "09:30", "100%" | 1.2.3, 09:30, 100% | Left bare |
| "0755", "01234", "0x1F", "2024-01-15" | 0755, 01234, 0x1F, 2024-01-15 | Left bare; see the note |
The last row is safe when the YAML is read back by this tool, but other parsers may treat a leading-zero value as an octal or decimal number, 0x1F as the integer 31 and 2024-01-15 as a date. Add quotes by hand to those values before using the YAML elsewhere. Keys are quoted unless they contain only letters, digits, underscores and hyphens and do not start with a digit or a hyphen. A key named on, yes, no, true or null is therefore written bare, and reading that YAML back here turns it into the key "true", "false" or "null".
YAML features this converter does not support
The parser covers the block-style subset that most config files use. These cases either stop with an error or convert differently from a full YAML library, so check for them before trusting the output.
- Anchors, aliases and merge keys. An anchor on a mapping (base: &base with keys nested below) stops with an indentation error. An alias such as *base is kept as the literal text "*base", and <<: is not expanded.
- Multi-document streams. The --- separators are skipped and all documents are merged into one object, with later keys overwriting earlier ones.
- Type tags. !!str 123 is output as the string "!!str 123" rather than being applied.
- Text blocks inside a list item. A step written as - run: | with the script on the following lines stops with an indentation error. Blocks work when the key sits in an ordinary mapping.
- Block indicators other than |, |-, > and >-. Forms such as |+ and |2 are not recognised and stop with an indentation error. The four supported forms all give the same result: no trailing newline is kept.
- Blank lines and extra indentation inside a text block. Blank lines are removed, every line is trimmed, and a line beginning with # is dropped as a comment.
- Lists directly inside lists (- - 1), inline collections that span several lines, plain values continued on the next line, and ? complex keys. Most of these stop with an error; a nested list under a key is returned as the text "- 1".
- A document that is a single bare value or a single-line [a, b] or {k: v} at the top level. The top level must be a block mapping or a dash list. A bare value or [a, b] stops with an error, but {k: v} is misread as one key and gives {"{k": "v}"}.
- Comments after an apostrophe. A quote character inside a plain value is treated as the start of quoted text, so msg: don't stop # note keeps the # note as part of the value.
- Escape sequences in double quotes other than \" and \n. A \t or \u00e9 is left exactly as typed.
- Duplicate keys. The last value wins and no warning is shown.
- JSON → YAML at 4 spaces with lists of objects. The second and later keys of each list item are indented too far, so the YAML will not parse; use 2 spaces.
- JSON → YAML with an empty [] or {} directly inside an array. It is written as an empty dash item, which reads back as null, or at 2 spaces as a stray -] or -} when the array is the top level of the document. An empty [] or {} that is the value of a key is written correctly.
Error messages and how to fix them
| Message | Typical cause | Fix |
|---|---|---|
| Line N contains a tab character. YAML must be indented with spaces only. | A tab anywhere in the text, including inside a value | Replace every tab with spaces |
| Line N: indentation does not line up with the block above it. | Sibling keys at different depths, or an unsupported construct such as an anchor, a nested list or a text block in a list item | Align the keys, or remove the unsupported feature |
| Line N: expected "key: value" but found "...". | No space after the colon (a:1), a bare line of text, or JSON pasted into the YAML side | Add the space, or switch Direction |
| That is not valid JSON: ... | Trailing comma, single quotes, comments or unquoted keys in JSON → YAML mode | Fix the JSON at the position given |
| Enter some YAML or JSON to get started. | Input is empty | Paste some text |
A list whose items contain several keys must have the later keys indented exactly two columns past the dash, in line with the first key.
When to quote a YAML value
YAML decides the type of an unquoted value by its shape, and JSON then records that decision permanently. The values worth quoting are the ones whose shape says something you did not mean: country and language codes such as NO, answers such as yes and off, versions such as 1.20 or 3.0, and anything with a leading zero such as a ZIP code, a phone extension or a file mode.
Parsers disagree on several of these. YAML 1.1 treats yes, no, on and off as booleans and reads 0755 as an octal number; YAML 1.2 treats the words as strings. This tool sits between the two: it applies the boolean words but refuses to convert anything that is not a plain canonical number. Converting a file here is therefore a quick way to see which values are at risk, but it does not guarantee that your deployment tool will type them the same way. Quotes remove the doubt in every parser.
For files that rely on anchors, several documents or text blocks inside list items, use a full YAML library instead. On the command line, yq -o=json file.yaml (the Go version of yq) prints JSON, and a short Python script using PyYAML's safe_load with json.dump does the same.
Step by step
- 1
Set Direction to YAML → JSON or JSON → YAML.
- 2
Paste your text into Input, replacing the sample deployment settings. YAML must be indented with spaces, not tabs.
- 3
Choose 2 spaces or 4 spaces under Indent. For JSON → YAML, keep 2 spaces if the data contains lists of objects.
- 4
Read the result in the JSON or YAML box, then copy it or download it as output.json or output.yaml.
- 5
If an error appears instead, go to the line number it names. The error table below explains each message.