What the JSON to YAML converter does
The converter writes your JSON as block-style YAML 1.2 (opens in a new tab): each key on its own line, nesting shown by indentation, and list items marked with a dash. Every JSON value has a YAML form, so the result reads back as the same data. Strings and numbers are copied from your text rather than recalculated, which keeps a 20-digit ID or a price of 9.90 exactly as it was. Keys stay in the order your JSON has them.
How to convert JSON to YAML
- Paste JSON into the input, or open or drop a
.jsonfile. - Pick the Indent. Two spaces is what the Kubernetes, Docker Compose and GitHub Actions documentation use.
- Leave YAML 1.1-safe output on unless you know that every program reading the file follows YAML 1.2.
- Copy the YAML or download it as a
.yamlfile. Swap direction sends it to YAML to JSON, which shows how the file reads back.
Examples
Input
{"service":{"image":"redis:7.4","ports":["6379:6379"],"healthcheck":{"retries":5}}}
Output
service:
image: redis:7.4
ports:
- 6379:6379
healthcheck:
retries: 5
Input
{"locale":"NO","debug":"off","window":"22:30","release":"3.10"}
Output
locale: "NO"
debug: "off"
window: "22:30"
release: "3.10"
Input
{"steps":[{"name":"Build","run":"npm ci\nnpm run build\n"},{"name":"Notify","run":"curl -X POST \"$HOOK\""}]}
Output
steps:
- name: Build
run: |
npm ci
npm run build
- name: Notify
run: curl -X POST "$HOOK"
Indentation and list style
YAML has two ways to write a collection. Block style puts every entry on its own line and shows nesting by indentation; flow style writes {a: 1, b: [2, 3]}, which is JSON with fewer quotes. Configuration files are almost always block style, so that is what the converter writes. Only an empty object or list keeps the flow form, {} or [], because a block collection cannot be empty.
Indent sets how far each level moves right: 2 spaces, the common choice for configuration, or 4 for teams that prefer wider steps. List items sit two spaces inside the key they belong to:
hosts:
- a.example.test
- b.example.test
Some formatters put the dash at the key's own column instead. Both layouts are valid YAML and mean the same thing, so any parser reads either.
When YAML needs quotes
YAML reads unquoted text by its look: true becomes a boolean, 42 a number and null nothing at all. The converter therefore leaves a string unquoted only when YAML would read it back as the same string, and quotes it in these cases:
- it looks like another type:
true,null,~,123,1.10,0x1For.inf; - it is empty, or starts or ends with a space;
- it contains
:or#, which YAML reads as a key separator and a comment; - it starts with a character that has a meaning of its own, such as
#,&,*,!,|,>,',",%,@, a backtick,[,{or a comma, or with-,?or:followed by a space.
Quote style chooses double or single quotes for these strings. Single quotes have no escapes, so a string with a control character, or with a single quote of its own, still gets double quotes. Characters that YAML cannot hold as they are, such as control codes, a byte order mark or the Unicode line separator, are written as escapes like \x7F or \L inside double quotes.
YAML 1.1-safe output
Many tools still read YAML by the rules of version 1.1. PyYAML, which Ansible uses, is one of them, and to them no is the boolean false, 0777 an octal number, 22:30 the number 1350 counted in base 60, 1_000 a thousand and 2024-01-01 a date. With YAML 1.1-safe output on, such strings are quoted too, so every parser reads text. Numbers with an exponent are adjusted for the same reason: YAML 1.1 reads 1e5 as text, so the converter writes 1.0e+5, the same value, and adds a note. How the two versions differ in detail is explained on YAML to JSON.
Multiline strings and block literals
A string with line breaks is written as a literal block: a | after the key, then the lines indented below it, each kept exactly. The character after the bar tells a parser what to do with the end of the text:
|keeps the one line break at the end, as files and scripts usually have;|-keeps none, for text that ends without a line break;|+keeps all of them, when the string ends with blank lines.
When the first line starts with spaces, a digit follows the bar, like |2, to say how deep the block is indented; otherwise a parser would count those spaces as indentation. Two kinds of text cannot be block literals and are written in double quotes with \n escapes instead: text with Windows line endings (\r\n), and text whose last line holds only spaces.
The converter does not write folded blocks (>). Folding joins lines with spaces when the file is read, so it suits prose, not certificates, scripts or SQL. If you prefer every string on one line, set Multiline strings to Quoted.
Kubernetes, Docker Compose and GitHub Actions
Kubernetes reads several manifests from one file when they are separated by ---. If your JSON is a list of objects, such as the items of a kubectl get -o json result, put the list itself in the input and turn on Top-level array as documents: each object becomes its own document, in the original order.
Docker Compose port mappings show why the YAML 1.1-safe output matters. A short mapping like 22:22 is a base-60 number to a YAML 1.1 parser, which is why the Compose documentation asks for ports as strings. The converter quotes exactly the mappings that need it and leaves 8080:80 as it is.
GitHub Actions workflows start with the key on. GitHub reads it as the string "on", but a YAML 1.1 parser reads a bare on as true, so YAML 1.1-safe output writes "on":, which GitHub reads the same way. Expressions like ${{ matrix.node }} need no quotes and stay as they are.
Options
| Option | Values | Default | When to change it |
|---|---|---|---|
| Indent | 2 spaces, 4 spaces | 2 spaces | Use 4 spaces only if your team's files already do; Kubernetes, Compose and GitHub examples use 2. |
| YAML 1.1-safe output | On, Off | On | Quotes strings like no, 0777 and 22:30, and gives exponents a point and a sign. Turn it off for strict YAML 1.2 readers that you want left with the shortest text. |
| Multiline strings | Block literal (|), Quoted | Block literal (|) | Quoted keeps each string on one line with \n escapes, which some diff tools show more clearly. |
| Top-level array as documents | On, Off | Off | Writes each item of a root array as its own document after ---, as Kubernetes manifests are kept. It has no effect on other input. |
| Line width | No folding, 80 characters, 120 characters | No folding | Folds long strings over several lines at a space. The value stays the same; block literals are never folded. |
| Quote style | Double ("), Single (') | Double (") | Single quotes for teams that prefer them; strings with escapes or a single quote still get double quotes. |
| Duplicate keys | Error, Use last value | Error | By default an object that repeats a key stops the conversion. Use last value keeps the last one, as JavaScript does, and lists the ones it drops. |
Common errors and fixes
| Code | What it means | How to fix it |
|---|---|---|
JSON_Error | One object names the same key twice, and a YAML mapping cannot hold a key twice. | Remove the member you do not want, or set Duplicate keys to Use last value. |
JSON_Warning | A string holds half of an escaped emoji or other character outside the basic plane, which a YAML file cannot store. | Repair the escape pair in the source data; the YAML shows the replacement character in its place. |
YAML_Note | A number with an exponent, like 1e5, was rewritten as 1.0e+5 so that YAML 1.1 parsers read a number too. | Nothing to fix: the value is the same. Turn off YAML 1.1-safe output to keep the number exactly as written. |
When the input is not valid JSON, the converter lists the syntax errors instead; the JSON Formatter explains each one with an example of the fix.