Skip to content

All tools (41)

JSON 6
Time & Date 4
Encoding & Decoding 4
Generators 3
Text & Data 4
Logs & Debugging 1
Config & Infra 3
Security & Hashing 4
Color & Design 5
Numbers & Bits 3
Web & Markup 4

Nothing leaves the cave.

Nothing you paste ever leaves your device. There is no server to send it to.

How you can check →
DevToolsCave

    This tool runs entirely in your browser. Nothing you paste is uploaded.

    How you can check →

    JSON to YAML

    JSON

    Convert JSON to YAML in your browser. Every value that a real YAML reader would misread is quoted, and the receipt shows exactly which readers agree.

    YAML
    The YAML appears here.

    Worked example: a Kubernetes Deployment, converted with the Kubernetes preset

    JSON (from kubectl get -o json)

    {
      "apiVersion": "apps/v1",
      "kind": "Deployment",
      "metadata": {
        "name": "cave-api",
        "labels": {
          "app": "cave-api",
          "version": "1.10"
        }
      },
      "spec": {
        "replicas": 3,
        "selector": {
          "matchLabels": { "app": "cave-api" }
        },
        "template": {
          "metadata": {
            "labels": { "app": "cave-api" }
          },
          "spec": {
            "containers": [
              {
                "name": "api",
                "image": "registry.example.com/cave-api:2026.09.12",
                "ports": [{ "containerPort": 8080 }],
                "env": [
                  { "name": "REGION", "value": "no" },
                  { "name": "LOG_LEVEL", "value": "debug" }
                ]
              }
            ]
          }
        }
      }
    }
    

    YAML

    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: cave-api
      labels:
        app: cave-api
        version: '1.10'
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: cave-api
      template:
        metadata:
          labels:
            app: cave-api
        spec:
          containers:
            - name: api
              image: registry.example.com/cave-api:2026.09.12
              ports:
                - containerPort: 8080
              env:
                - name: REGION
                  value: 'no'
                - name: LOG_LEVEL
                  value: debug

    Verified — converting back gives the same 15 values in the same order. Safe for 6/6 readers. 2 notes: "metadata.labels.version" is quoted because a YAML parser would read it as a number.

    What YAML changes about your data

    Nothing — and everything, depending which question you mean. The values in a JSON document and the values in its YAML equivalent are the same values: the same string, the same number, the same array in the same order. What changes is how a YAML reader decides what a bare word means, and that decision is where every head-of-search converter gets measurably wrong answers. A YAML parser looks at unquoted text and has to guess whether no is a string or the boolean false, whether 0777 is decimal 777 or octal 511, whether 12:30 is a string or the sexagesimal number 750. JSON never asks this question — a string is always quoted — so converting to YAML is the first time your data is exposed to a reader's guesswork at all. This tool's whole job is making sure that guess always lands on the value you actually had.

    Why "no" and "1.10" get quoted

    YAML 1.1 — the spec SnakeYAML, PyYAML and go-yaml v2 implement, which means Spring Boot, Ansible and Kubernetes tooling — resolves a bare no, off, n or NO to the boolean false. A country code, a feature flag, or a two-letter region written bare stops being the text you wrote the moment a 1.1 reader opens the file. Likewise 1.10 written bare is the number 1.1 to every YAML reader regardless of spec — the trailing zero, which is exactly the digit that distinguishes a version label from a smaller number, is silently gone. This tool's quoting predicate checks the union of six real reader profiles rather than one spec, so a value is quoted the moment any of them would misread it — never only the one you happened to pick.

    Six real YAML readers and what they do with three traps
    Reader Spec Used by no y 1e3
    YAML 1.2 core1.2js-yaml 4, yaml 2, ruamel, yq (Go)texttextnumber
    PyYAML1.1PyYAML, Ansible, Home Assistantfalsetexttext (needs a signed exponent)
    SnakeYAML1.1SnakeYAML, Spring Boot, Jenkinsfalsetexttext
    go-yaml v21.1Kubernetes tooling, Helm, kubectlfalseboolean truetext
    go-yaml v31.2-ishCompose v2, many Go CLIstexttextnumber
    Psych1.1Ruby, Rails, GitLab CIfalsetexttext

    Sequence indentation styles, and who uses which

    YAML allows a block sequence's dash either flush with its parent key or indented two spaces under it — both parse identically, but house styles disagree, which is why this tool exposes it as an option rather than picking silently. Kubernetes manifests and Compose files nearly always indent ( - a under the key); GitHub Actions workflows and Ansible playbooks are usually flush (- a at the same column as the key). The four preset chips above set this along with the other style options a switcher would otherwise hunt through a menu for.

    Block scalars

    A JSON string containing newlines becomes a YAML block scalar rather than an escaped one-liner, because |-style block text is what a human editing the file actually wants to read. The exact trailing-newline behaviour matters: | keeps exactly one trailing newline, |- strips it, and |+ keeps every trailing blank line — this tool picks whichever spelling reproduces your string's exact bytes, and the verification receipt is how it knows it chose correctly rather than approximately.

    Why comments from JSONC survive

    Files like tsconfig.json, .eslintrc.json and VS Code settings are JSONC — JSON with // and /* */ comments the strict spec does not allow. Most converters read these with a JSON.parse-compatible loader and drop every comment silently. This tool's JSON engine keeps a comment's exact text and position on a side list rather than discarding it, so a comment above a key can be attached to the same key in the YAML — turning a config file's original context into # lines rather than losing it on the way across.

    The six readers and what each would do with the other tools' output

    Measured directly (2026-09-12): the two most common libraries behind competing converters write no, 12:30 and 2024-01-15 unquoted by default — correct for a YAML 1.2 reader, wrong the moment the file reaches SnakeYAML, PyYAML or go-yaml v2. Nobody in that field prints which reader their output is actually safe for. This tool's reader matrix (the Readers tab above) answers that question directly, per conversion, for the six profiles it tracks — a checkmark per reader is a claim you can verify, not an assumption you have to trust.

    The numbers no YAML reader keeps exactly

    A 20-digit id like a Snowflake ID or a bigint database key survives this conversion as the exact digits it started as — this tool's JSON engine never routes a number through a 64-bit float. But the receipt is honest about what happens next: if you then open that YAML with js-yaml or PyYAML, their loader will round it to the nearest representable double, because that is what those libraries do internally regardless of what the file says. The receipt names this ("some JSON readers would round this") rather than implying the number is safe everywhere just because it left here correctly.

    Doing this from the terminal

    Three common ways to do the same conversion outside a browser, each with the caveat that matters:

    • yq -o=yaml input.json — mikefarah's yq uses a 1.2-family YAML library, so it will not add the quoting a 1.1 reader like SnakeYAML or Ansible needs.
    • python -c 'import yaml, json; print(yaml.safe_dump(json.load(open("input.json"))))'json.load already rounds any integer past 2^53 written as a JSON number, and PyYAML's safe_dump will not quote a bare no for you; it writes whatever Python's own type already is.
    • node -e "console.log(require('js-yaml').dump(JSON.parse(require('fs').readFileSync('input.json','utf8'))))"JSON.parse has the same 2^53 problem, and js-yaml's dump quotes some traps (the single-letter booleans) but not others (a bare 1_000).

    Common use cases

    • Turning a kubectl get -o json dump into a manifest you can hand-edit and reapply
    • Converting a Terraform or AWS CLI JSON export into readable YAML for a docs repo
    • Checking which YAML readers would safely reproduce a JSON config before shipping it
    • Turning NDJSON log output into multi-document YAML for inspection
    • Carrying JSONC comments from a settings file into a hand-maintained YAML equivalent

    Frequently asked questions

    Why is my string quoted?
    Because at least one real YAML reader would misread it bare. "1.10" is quoted because a bare 1.10 is the number 1.1 to every YAML parser — the trailing zero, which is exactly the part that matters in a version label, would vanish. "no" is quoted because YAML 1.1 (SnakeYAML, PyYAML, go-yaml v2 — Spring Boot, Ansible, Kubernetes tooling) reads a bare no as the boolean false. The receipt names the reason for every value it quotes.
    Why is "1e-7" now "1.0e-7"?
    Because PyYAML's own float resolver requires a literal "." in the mantissa and a signed exponent — its pattern is [-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)?, with no `?` on the exponent's sign. A bare 1e-7 fails that pattern and stays a string to PyYAML and Ansible, even though every YAML 1.2 reader parses it as a float. Rewriting it to 1.0e-7 — a dot in the mantissa, a signed exponent — is the one spelling every reader profile in the matrix agrees is a number, and the receipt notes the rewrite by name.
    Can I get ~ instead of null?
    Yes — the "Null as" option in YAML style writes ~ or an empty value instead of the word null. All three spellings are unambiguous in both YAML 1.1 and 1.2, so this is a pure style choice with no correctness trade-off.
    Will Kubernetes read this?
    Check the Readers tab. Kubernetes tooling reads YAML through go-yaml v2, a YAML 1.1 implementation with its own quirks — it has the single-letter y/Y/n/N booleans that PyYAML and SnakeYAML both omit. This tool's quoting predicate is built from the union of every profile it tracks, so a value safe under go-yaml v2 is also safe under PyYAML, SnakeYAML, js-yaml and the rest — the matrix is where you can see that guarantee is actually holding for your file, not just asserted.
    Where did my 20-digit id go?
    Nowhere — it is written out digit for digit. JavaScript's own JSON.parse would silently round a number past 2^53 (9,007,199,254,740,991), which is exactly the range a Snowflake ID or a bigint database key lives in. This tool's JSON engine keeps the original digits as text throughout, so the YAML has the same number your JSON had, verbatim.
    Does the JSON leave my browser?
    No. Parsing, converting and verifying all run in this tab's own JavaScript — nothing is uploaded, logged or stored. You can confirm it by opening the Network tab before you paste.