Convert YAML to JSON
YAML rewrites more of your data than you think. This one counts every value it changed, instead of handing back JSON and staying quiet.
Runs in your browser0 bytes uploadedYAML rewrites more of your data than you think. This one counts every value it changed, instead of handing back JSON and staying quiet.
Runs in your browser0 bytes uploadedno and yes stay text, and a date stays a string. This is the current spec, and what modern JavaScript parsers do. Pick this unless you know your file is read by something older.
Nothing at the counter yet. Paste YAML, drop a .yml file anywhere on the panel to the left, or press Use an example.
Converting YAML to JSON sounds mechanical. Both formats hold the same six kinds of value, the shapes map one to one, and a converter that walks the tree and prints braces will look correct on almost every file you feed it. The trouble is not the shape. It is that YAML decides what your scalars mean before the shape is ever built, and some of those decisions are surprising enough that people have shipped outages over them.
The famous one is the Norwegian country code. Write country: NO and a YAML 1.1 parser reads it as the boolean false, because 1.1 acceptsno, yes, on, off, y andn as ways of writing true and false. Your two-letter country code stops being a country. Nothing warns you, the file is still valid, and the failure shows up much later somewhere that has no idea a YAML parser was involved.
The one that catches more people, and gets talked about far less, is the leading zero. Writezip: 01234 and there is no version of YAML that keeps it intact. Under 1.2 it is read as a decimal number and comes out as 1234. Under 1.1 the leading zero means octal, so the same five characters come out as 668. Two different wrong answers for one value, and the same applies to phone numbers, account numbers, part codes and every other label that happens to be made of digits. There is no setting that repairs it, because nothing in the file says the value was meant to be text — the only real fix is quoting it at the source. This converter cannot fix your file either, but it will tell you exactly which values it happened to, which is more than the alternatives do.
The same goes for the handful of things JSON simply cannot hold. .nan and.inf are legal YAML numbers with no JSON spelling, so they land in your output as null — a value that reads as "nothing was here" rather than "something was here and could not be written". An integer longer than about nineteen digits loses its tail the moment it becomes a JavaScript number. Each of these is counted and named on the receipt rather than allowed to slip through.
| Full name | YAML Ain’t Markup Language |
|---|---|
| Extension | .yaml, .yml |
| Format type | Human-readable data serialization — indentation is syntax |
| MIME type | application/yaml |
| Full name | JavaScript Object Notation |
|---|---|
| Extension | .json |
| Format type | Nested text data, six value kinds |
| MIME type | application/json |
YAML 1.2 removed the boolean-looking words and the octal-by-leading-zero rule. That was 2009. The reason the problem is still alive is that the ecosystem never finished moving: plenty of widely used parsers still implement 1.1, and a file that travels between two tools can be read two different ways without anyone editing it.
The table below names only libraries whose behavior is easy to state, and it is worth knowing that some sit between the two columns rather than in one of them. Go's yaml.v3, for instance, reads a bare no as the string when the destination is untyped, but still accepts it as false when the field it is filling is a boolean — deliberate partial compatibility with the older rules. That is exactly why this page shows you both readings rather than telling you which one your toolchain will pick.
| Reads YAML 1.1 | Reads YAML 1.2 | |
|---|---|---|
| Parsers that behave this way | PyYAML, Ruby's Psych, go-yaml v2 — the route most Kubernetes tooling takes | js-yaml 4 and the yaml package on npm, both of which we ran to build this page |
country: NO | false | "NO" |
version: 010 | 8 | 10 |
time: 12:30 | 750 | "12:30" |
when: 2001-12-14 | a timestamp | "2001-12-14" |
The tool above defaults to 1.2, because that is what the current spec says and what most new tooling implements. But the version switch is not really the point of the page. Whatever you pick, the panel on the right lists every scalar the two versions disagree about, with both readings side by side, so you find out that the ambiguity exists without having to already suspect it. A setting can only help someone who knows to look for it; a list finds the people who do not.
One narrow case is worth knowing because it bites in exactly the file people convert most. A port mapping written 22:22 is read by YAML 1.1 as a sexagesimal number and becomes 1342. 80:80 and 3000:3000 survive, because the part after the colon has to be under sixty for the rule to apply. That is the kind of distinction a rule of thumb gets wrong, which is why the tool compares actual parses rather than guessing from a list of suspicious-looking words.
YAML can point at itself. An anchor written &defaults marks a block, an alias written *defaults reuses it, and <<: merges one mapping into another. JSON has no equivalent for any of it, so all three are expanded into full copies. That is the only honest option, and it explains a result people otherwise find alarming: a small YAML file can become a much larger JSON file with the same block repeated several times.
Two failure modes come with that, and both are handled rather than left to the browser. An anchor that contains its own alias describes a value that holds itself forever; the tool finds the loop while reading and names the anchor, instead of letting the serializer run out of stack. A file that references a handful of anchors in layers can expand to gigabytes from a few hundred bytes — the classic billion-laughs shape — and that is stopped before the expansion rather than after the tab has died.
A YAML file can hold several documents separated by ---, which is how a stack of Kubernetes manifests usually travels. JSON has no concept of that at all, so there is no single right conversion and the tool does not pretend otherwise. It counts the documents before it converts anything and offers three outcomes: one JSON array holding all of them, JSON Lines with one document per line, or the first document alone. Taking the first silently is what most converters do, and it is the reason people discover a fortnight later that two thirds of their file never arrived.
YAML errors are almost always indentation, and almost never where a generic message suggests. A key that sits one space too far left ends a block early; a tab where spaces were expected is rejected outright, because YAML forbids tabs for indentation and most editors insert them without asking. The tool reports the line and column, quotes the line with a caret under the offending column, and gives advice that matches the actual failure rather than a single sentence covering every case. If the input turns out to be JSON rather than YAML — which is legal, and common when someone pastes the wrong buffer —the JSON formatter is the better place to look at it.
| YAML | JSON | |
|---|---|---|
| Full name | YAML Ain't Markup Language | JavaScript Object Notation |
| Extensions | .yaml, .yml | .json |
| Registered media type | application/yaml | application/json |
| Comments | Yes, with # | None at all |
| References within a file | Anchors and aliases | None |
| Documents per file | Many, split by --- | One |
| Key types | Any node, including collections | Strings only |
| Structure carried by | Indentation | Braces and brackets |
Two footnotes on that table. The media type was only registered in February 2024, by RFC 9512; before that everyone used text/yaml or application/x-yaml, which were never registered and are now best treated as historical spellings. And.yml versus .yaml is not a distinction at all — same format, same parser, and the shorter spelling survives mostly because Docker Compose, GitHub Actions and a generation of CI tools chose it.
The comment row is the one to read twice. Every # line in your source is gone the moment the file becomes JSON, and no tool anywhere can prevent that. If the JSON is a build artifact nobody will edit, it does not matter. If the JSON is about to become the file your team works in, the comments were often the only record of why a setting is what it is, and they are worth copying somewhere first. The receipt counts them so the loss is at least a number you saw.
Going the other way is a much smaller problem, and worth stating plainly: every JSON document is already valid YAML. JSON is a subset of the format, so a JSON file can be renamed and fed to a YAML parser unchanged. Converting to idiomatic block-style YAML is a formatting job rather than a translation, which is why it does not need the warnings this page is built around.
The parser is a JavaScript module the page fetches the first time you hand it something, and the conversion is a function call on the text sitting in the textarea. No part of that code path builds a request, because there is no server component to send one to — the whole site is static files, and this page is the same static file for everyone who opens it.
That matters more here than the file sizes suggest, because of what YAML is usually used for. A docker-compose.yml carries database passwords and registry credentials. A Kubernetes manifest carries internal hostnames, service accounts and image pull secrets. A CI workflow carries the shape of your deployment and often the names of the environments it reaches. Pasting any of those into a converter that posts them somewhere is a credential disclosure with a friendly interface, and the industry standard for this category is a page that says it is private while loading two dozen advertising origins. You do not have to take our word for it either: open the browser's developer tools, watch the requests, and note that handing this page a file produces none. If you would rather read how to check that properly, the guide on verifying local processing walks through it. Once the JSON is out, the JSON to JavaScript converter will turn it into an object literal that actually runs.
Because YAML 1.1 treats no, yes, on, off, y and n as booleans, and the Norwegian country code is spelled exactly like one of them. YAML 1.2 removed that rule, so a 1.2 parser reads NO as the two-letter string it looks like. The trouble is that both versions are still in daily use: PyYAML, Ruby's Psych and anything reaching Kubernetes through go-yaml v2 read it the old way, while current JavaScript parsers read it the new way. Some libraries sit in between — Go's yaml.v3 gives you the string when the target is untyped but still accepts the value as a boolean when the field is one. Your file is therefore not one thing; it depends on who opens it. This converter defaults to 1.2 and shows you every scalar the two versions disagree about, with both readings side by side, so you can see the ambiguity rather than inherit it. Quoting the value in the source is the permanent fix.
It was read as a number, and numbers do not keep leading zeros. This one catches people out because it goes wrong in both versions of YAML and in different ways: under 1.2 the value 01234 becomes 1234, and under 1.1 the same text is octal and becomes 668. Neither is your zip code. The same applies to phone numbers, account numbers, part codes and anything else that is a label made of digits rather than a quantity. There is no setting that fixes it, because nothing in the file says the value is meant to be text. The fix is in the source: put quotes around it, and it stays a string in every parser. This tool lists each value it turned into a number so you can find them.
They are expanded, because JSON has no way to write a reference down. An anchor marked with &name and used later as *name becomes a full copy of the value at every place it was referenced, so a document that repeated one block four times comes out with that block written four times. Merge keys, the << syntax that pulls one mapping into another, are applied rather than carried through as a literal key named <<. The receipt counts both, since a JSON file that is suddenly much larger than the YAML it came from usually has an anchor behind it. Anchors that refer to themselves are caught and explained instead of hanging the tab, and a document with an unreasonable number of aliases is stopped rather than allowed to exhaust memory.
You choose, and the count is shown before the conversion rather than after. JSON has no concept of multiple documents in one file, so there is no single correct answer. The default wraps them in a JSON array, which loses nothing. JSON Lines writes one document per line, which is what streaming consumers usually want. The third option takes only the first document, which is what many converters do without saying so — the difference here is that it is a choice you made and the other documents are still counted on the receipt. Kubernetes manifests and OpenAPI bundles are the usual reason this matters.
No, and nothing can save them. JSON has no comment syntax at all, so every # line in your YAML is gone the moment it becomes JSON. This is worth knowing before you convert a config file you intend to keep working in, because comments in a docker-compose.yml or a CI workflow are often the only record of why a setting is what it is. If the JSON is a build artifact, it does not matter. If the JSON is going to become the file people edit, copy the comments somewhere first. The tool counts the comments it dropped so the number is at least visible.
No. They are the same format and the same parser reads both. The three-letter spelling is the one the YAML project recommends, but .yml became common on Windows and in tooling that predated the recommendation, which is why Docker Compose, GitHub Actions and countless CI systems use it. Nothing about the contents changes with the extension, and this converter does not care which one you drop on it. It accepts pasted text with no extension at all, which is how most snippets arrive.