The first time YAML burned me properly, it was a country code. I was moving a locale configuration out of a Laravel project's JSON files into a deployment-friendly YAML format, hand-converting as I went because "it's just changing braces to indentation." One of the entries was Norway: "country": "NO". In YAML, unquoted, that's not a string โ under the YAML 1.1 rules that PyYAML and plenty of other parsers still apply, NO is the boolean false. The deploy script, written in Python, cheerfully evaluated Norwegian users as country: false and routed them to the fallback locale. This bug has a name โ the community calls it the Norway problem โ and I got to discover it the artisanal way, one confused support ticket at a time.
Hand-converting JSON to YAML looks trivial and is actually a minefield, because the two formats have wildly different ideas about what a bare word means. In JSON, everything is explicit: strings have quotes, numbers don't, true/false/null are keywords, end of story. In YAML, an unquoted scalar gets interpreted: no becomes false, 3000 becomes an integer, 1.10 becomes the float 1.1 (goodbye, version string), 08 chokes some parsers as an invalid octal, and a value with a stray colon-space becomes a nested map when you least expect it. Every one of these is a silent data corruption โ the file parses fine, the types are just wrong.
A JSON to YAML converter that understands these rules gets you the readability YAML was invented for without the type roulette. The one I built for toolz.dev detects every ambiguous scalar โ boolean look-alikes, number look-alikes, YAML 1.1 legacy values, strings with special characters โ and quotes exactly those, so what was a string in your JSON is still a string after the next tool parses the YAML. That "exactly those" matters: quoting everything would be safe too, but the output stops looking like idiomatic YAML, and idiomatic is the whole point.
This guide covers how the conversion handles YAML's sharp edges, why JSON is technically already YAML (and why that fact doesn't help you), and the Kubernetes, CI, and Docker Compose workflows where this conversion happens weekly.
TL;DR: Paste JSON into the toolz.dev JSON to YAML Converter, pick 2- or 4-space indentation, and get clean block-style YAML with type-safe quoting โ
"3000"stays a string,"no"stays a string,"1.10"stays a version. Key order is preserved, empty collections come out as[]and{}, and everything runs client-side so configs with secrets never leave your browser. Round-trip back with the YAML Validator, and format the source first with the JSON Formatter.
Isn't JSON Already Valid YAML?
Yes โ and it's the most useless "yes" in configuration management. YAML 1.2 was explicitly designed as a superset of JSON: every valid JSON document parses as valid YAML. You could paste raw JSON into a Kubernetes manifest and kubectl would accept it.
Nobody does this, because the reason YAML exists is human ergonomics. Kubernetes manifests, GitHub Actions workflows, Docker Compose files, Ansible playbooks, Home Assistant configs โ these are YAML because people read and hand-edit them constantly, and replicas: 3 under an indented block scans better than {"replicas":3} nested in braces. When someone says "convert JSON to YAML," they mean block-style YAML: indentation instead of braces, - dashes instead of bracketed arrays, no quotes where none are needed.
That last clause is where the difficulty lives. Going from JSON's everything-explicit syntax to YAML's minimal syntax means deciding, for every string, whether it can safely lose its quotes โ and that decision requires knowing YAML's scalar resolution rules better than most humans reliably do at 5 PM on a Friday. That's the actual job of a converter; the braces-to-indentation part is trivial.
What Silently Breaks When You Hand-Convert?
The failure cases fall into four families, and I've hit every one of them in real configs:
Boolean look-alikes. YAML 1.1 resolves yes, no, on, off, y, n (in various casings) as booleans, and YAML 1.2 keeps true/false. PyYAML โ still the default YAML library in most Python codebases โ implements 1.1. So "debug": "no" hand-converted to debug: no becomes debug: false in your Python deploy tooling. The Norway problem (NO โ false) and its cousin the Ontario problem (ON โ true) are this family's greatest hits.
Number look-alikes. "port": "3000" converted to port: 3000 is now an integer. Kubernetes doesn't care in some fields and hard-fails in others โ env var values, for instance, must be strings, and kubectl apply will reject an integer there with an error that names the field but not the why. Version strings are worse because nothing fails: version: 1.10 parses as the float 1.1, and your deploy script happily reports the wrong version forever. Leading zeros โ postal codes, phone numbers, octal-looking IDs like 0755 โ round out the family.
Special characters. A colon followed by a space inside an unquoted value starts a mapping (message: error: not found is a parse error or a nested map, parser depending). A # starts a comment mid-value. Leading *, &, ! collide with YAML's anchor, alias, and tag syntax. Strings with newlines need escaping or block scalars.
The empty string. Unquoted emptiness in YAML is null, not "". Any JSON field holding an empty string must come out quoted or it changes type.
The converter checks every string against all four families and quotes the ones that need it โ and only those. production comes out bare because it's unambiguous; "3000", "no", "1.10", and "" come out quoted because they aren't. There's also a "Quote all strings" toggle for when you're feeding a parser you don't trust and want zero scalar resolution happening at all.
How Do You Convert JSON to YAML With the Tool?
Step 1: Paste Your JSON
Any valid JSON works โ objects, arrays, deep nesting, unicode. The Load Sample button gives you a realistic service config that exercises the interesting cases: a numeric string port, a boolean, an empty array, nested maps. If your input has syntax problems, the converter reports the parser's exact error rather than converting a truncated document; for hunting down where the error is in a big blob, the JSON Formatter is the better microscope.
Step 2: Choose Indentation
Two spaces or four. Two is the overwhelming convention โ Kubernetes docs, GitHub Actions examples, Docker Compose references, and the yamllint defaults all use it โ but some teams standardize on four for readability in deep nesting. Whichever you pick, the converter is consistent about it, including the subtle case of list items under a key, where inconsistent hand-indentation is a classic source of "mapping values are not allowed here" errors.
Step 3: Convert and Review
The output appears with line and byte counts. Skim it once โ not for correctness (that's the converter's job) but to sanity-check the quoting decisions against your expectations. Seeing PORT: "3000" quoted while NODE_ENV: production isn't is the tool telling you which values were dangerous.
Step 4: Copy or Download
Copy to clipboard for pasting into an existing manifest, or download as a .yaml file. The output uses spaces only โ YAML forbids tabs for indentation, which is worth knowing when you later edit the file in an editor configured for tab indentation.
JSON vs YAML: When Does Each Format Win?
| JSON | YAML | |
|---|---|---|
| Read/edited by | Machines, APIs | Humans, ops teams |
| Comments | Not in the spec | # comments โ the killer feature for configs |
| Type explicitness | Total โ quotes decide everything | Scalar resolution โ context decides |
| Multiline strings | \n escapes only |
Block scalars (` |
| Parse speed & ubiquity | Fastest, everywhere | Slower, heavier parsers |
| Foot-guns | Trailing commas, that's about it | Norway problem, tabs, indentation drift, version truncation |
| Natural habitat | API payloads, package.json, data interchange |
Kubernetes, CI pipelines, Compose, Ansible |
The pattern behind the table: JSON wins wherever a machine writes and a machine reads; YAML wins wherever a machine reads but a human writes. Configuration sits squarely in the second category, which is why the JSON-to-YAML direction is the common one โ data starts life in an API or a database export and needs to become something an ops team can maintain. The reverse trip, YAML back to machine-readable JSON, is what the YAML Validator handles โ paste YAML, get validation plus the equivalent JSON.
What Are the Everyday Workflows for This Conversion?
Kubernetes Manifests from API Output
kubectl get deployment my-app -o json gives you JSON; the manifest you check into Git is YAML. Converting API responses into clean YAML is the fastest way to bootstrap a manifest from a live resource โ convert, strip the server-populated status and metadata.managedFields blocks, and you have a declarative starting point. The type-safe quoting earns its keep here: env values in Kubernetes must be strings, and the converter's insistence on quoting "3000" is the difference between kubectl apply succeeding and failing.
CI Pipeline Configuration
GitHub Actions and GitLab CI are YAML-only. When I'm generating workflow steps programmatically โ a matrix of PHP and Node versions for testing WP Adminify against, say โ the generator naturally produces JSON, and the last step is conversion. Version strings in test matrices are exactly the values that get mangled by naive conversion: a matrix of ["1.9", "1.10", "1.11"] hand-converted without quotes tests against PHP 1.1 twice. The coding tools collection covers more of this generate-then-convert pattern.
Docker Compose from Inspect Output
docker inspect emits JSON; docker-compose.yml wants YAML. Reverse-engineering a Compose file from a running container โ ports, volumes, env โ is a convert-and-prune job. Empty arrays and objects convert to [] and {} flow syntax, which Compose accepts and which keeps the pruning stage readable.
Making Config Reviewable
This one is underrated: JSON configs with dozens of nested keys are miserable in code review, partly because they can't carry comments. Converting to YAML lets you annotate why rateLimit is 250 right next to the value. For the review itself, pairing the conversion with a structural diff of before/after JSON keeps the "what actually changed" question honest while the YAML version handles the "why."
OpenAPI and Schema Documents
OpenAPI specs are commonly authored in YAML but generated and served as JSON. Converting a generated spec to YAML for human editing โ then validating the round trip โ is standard API-team workflow, and the fidelity guarantees (key order preserved, types quoted) mean the YAML version stays diffable against its JSON ancestor.
Why Does Key Order Preservation Matter?
Per the JSON specification, object key order carries no meaning โ {"a":1,"b":2} and {"b":2,"a":1} are the same object. So a converter could sort keys alphabetically and be technically correct. It would also be practically hostile, because config files are read in order: a Kubernetes deployment reads naturally as apiVersion, kind, metadata, spec โ sorting those alphabetically produces a manifest that parses identically and reads like a ransom note.
The converter emits keys in source order. Your mental model of the document survives the conversion, the YAML diffs cleanly against previous conversions of the same source, and conventional orderings (name before value, apiVersion first) stay conventional. If you want canonical ordering for comparison purposes, that's a diff-tool concern โ the JSON Diff Checker compares by key regardless of order, which is the right layer for that problem.
Is It Safe to Convert Configs Containing Secrets?
Configuration is the most secret-dense text a developer handles โ database URLs with embedded passwords, API tokens in env blocks, internal hostnames that map your infrastructure. It's also exactly what people paste into online converters, usually mid-deploy, usually in a hurry.
The toolz.dev converter runs entirely in your browser: parsing, scalar analysis, serialization โ all of it is client-side JavaScript, no network request carries your data, and the tool keeps working with your connection cut. That's an architecture fact, not a privacy-policy promise. The browser-first design philosophy behind the whole toolbox is laid out in the web developer toolkit guide; this tool is that philosophy applied to the single most sensitive document type in your workflow.
The obvious caveat stands: client-side conversion protects the conversion. Where you paste the output afterward is its own security decision.
FAQ
How do I convert JSON to YAML online?
Paste your JSON into the JSON to YAML Converter, choose 2- or 4-space indentation, and click Convert. You get block-style YAML with type-safe quoting, ready to copy or download as a .yaml file. The conversion runs entirely in your browser โ nothing is uploaded.
Is JSON already valid YAML?
Technically yes โ YAML 1.2 is a superset of JSON, so any valid JSON document parses as YAML. But JSON syntax defeats YAML's readability purpose. Converting produces block-style YAML with indentation instead of braces, which is what Kubernetes manifests, CI workflows, and Compose files expect humans to read and edit.
What is the Norway problem in YAML?
Under YAML 1.1 scalar rules, which parsers like PyYAML still apply, the unquoted values no, yes, on, and off parse as booleans โ so the country code NO silently becomes false. The converter prevents this by automatically quoting any string that a YAML parser could interpret as a boolean, number, or null.
Will numeric strings like "3000" stay strings after conversion?
Yes. The converter detects strings that look like numbers and quotes them in the output, so "3000" remains a string instead of becoming the integer 3000. This matters for ports, version numbers like "1.10" (which would otherwise truncate to the float 1.1), postal codes, and IDs with leading zeros.
Does the converter preserve the order of my JSON keys?
Yes. Keys are emitted in the order they appear in the source JSON. Sorting keys would be technically valid โ JSON object order carries no meaning per RFC 8259 โ but source order keeps configs readable in their conventional structure and keeps the YAML diffable against its JSON source.
Can I use the output directly in Kubernetes or Docker Compose?
Yes. The output is standard block-style YAML indented with spaces (never tabs), which kubectl, Docker Compose, GitHub Actions, and GitLab CI all accept. Values that must be strings โ like Kubernetes env var values โ come out quoted, avoiding the type errors kubectl raises on unquoted numerics.
How do I convert YAML back to JSON?
Use the YAML Validator on toolz.dev โ it parses your YAML, reports any syntax errors, and outputs the equivalent JSON. Together with the JSON to YAML Converter, it gives you a full round trip between the two formats.
Is it safe to convert configuration files that contain secrets?
Yes. The conversion runs entirely in JavaScript in your browser โ no network request carries your data, nothing is stored or logged, and the tool works offline. Configs with database credentials, API tokens, or internal hostnames never leave your machine.
YAML's readability is real, and so are its sharp edges โ the format resolves types from context, and context is exactly what hand-conversion gets wrong. A converter that knows the scalar rules gives you the readable config without the silent type corruption: convert your JSON, skim the quoting it chose, and ship a manifest where Norway is still a country.

