Browser-native file tools

Convert YAML to CSV

Paste a YAML list of mappings — get a clean CSV. Nested keys flatten with dot notation. Files never leave your browser.

— or paste YAML below
Delimiter:

How to convert YAML to CSV

Paste your YAML into the converter at the top of this page (or upload a .yaml/.yml file). The tool expects a top-level list of mappings — the most common shape for config exports — and produces a CSV where each list item is a row and each key is a column. Pick the delimiter (comma/semicolon/tab) and download. Runs entirely in your browser.

Nested mappings are flattened with dot notation (metadata.namespace becomes one column). Inline lists (ports: [80, 443]) are kept as JSON-stringified values. Going the other direction? See CSV to YAML.

YAML to CSV examples

Kubernetes pods

A common workflow: dump pod info with kubectl get pods -o yaml, post-process with yq, paste here.

- name: web-7d9f
  namespace: production
  status: Running
  node: ip-10-0-1-23
  restarts: 0
- name: api-5f4b
  namespace: production
  status: Running
  node: ip-10-0-1-47
  restarts: 2
- name: worker-b6c2
  namespace: jobs
  status: CrashLoopBackOff
  node: ip-10-0-2-11
  restarts: 14

Becomes:

name,namespace,status,node,restarts
web-7d9f,production,Running,ip-10-0-1-23,0
api-5f4b,production,Running,ip-10-0-1-47,2
worker-b6c2,jobs,CrashLoopBackOff,ip-10-0-2-11,14

GitHub Actions workflow jobs

Paste the jobs: map after running yq '.jobs | to_entries | map({name: .key, runs_on: .value."runs-on", needs: (.value.needs // [])})' against your workflow file.

- name: lint
  runs_on: ubuntu-latest
  needs: []
- name: test
  runs_on: ubuntu-latest
  needs: ["lint"]
- name: deploy
  runs_on: ubuntu-22.04
  needs: ["test"]

Generic config export

- service: auth
  region: us-east-1
  config:
    timeout_ms: 5000
    retries: 3
- service: billing
  region: eu-west-1
  config:
    timeout_ms: 8000
    retries: 5

Flattens to columns service, region, config.timeout_ms, config.retries.

Flattening nested YAML

The flattener walks one level deep. user: {name: Ada, email: ada@lovelace.io} becomes columns user.name, user.email. For deeper nesting (user.address.city), reshape with yq first:

yq '.[] | {id, name: .user.name, city: .user.address.city}' input.yaml

Inline lists are written as JSON-encoded strings — tags: [prod, web] becomes "[\"prod\",\"web\"]" in the cell. To get one row per tag, explode first with yq '.[] | . as $r | .tags[] | $r * {tag: .} | del(.tags)'.

How to convert YAML to CSV in Python, yq, or Ruby

Python (PyYAML + pandas)json_normalize does the same dot-notation flattening as the converter above:

import yaml, pandas as pd
data = yaml.safe_load(open("input.yaml"))      # never use load() on untrusted input
pd.json_normalize(data).to_csv("out.csv", index=False)

yq (the Go version) ships a CSV output mode:

yq -o=csv '.' input.yaml > out.csv
yq -o=csv '.[] | [.name, .namespace, .status]' pods.yaml > pods.csv

The Python yq (a jq wrapper) doesn’t support -o=csv — pipe through jq -r instead: yq -j '.' input.yaml | jq -r '.[] | [.name, .age] | @csv'.

Ruby:

require "yaml"; require "csv"
data = YAML.safe_load_file("input.yaml")
keys = data.flat_map(&:keys).uniq
CSV.open("out.csv", "w") { |csv| csv << keys; data.each { |r| csv << keys.map { |k| r[k] } } }

Common YAML-to-CSV problems

”YAML anchors/aliases not supported”

YAML lets you DRY up repeated blocks with &anchor and *alias:

defaults: &defaults
  timeout: 30
  retries: 3
- name: web
  <<: *defaults

The converter doesn’t expand these — pre-process with yq 'explode(.)' first, which inlines anchors:

yq 'explode(.)' input.yaml > expanded.yaml

“Multi-document streams not supported”

Files with --- separators between documents (common for kubectl get all -o yaml) are split by the YAML spec into multiple docs. The converter only reads the first one. Split first:

yq 'select(documentIndex == 0)' input.yaml      # first doc
yq -s '.' input.yaml                             # all docs as one list

The second form merges every doc into a single top-level list — paste that into the converter.

”Block scalars not supported”

Long strings written with | (literal) or > (folded) aren’t supported in this minimal parser:

- name: example
  description: |
    A multi-line
    description

Convert block scalars to inline quoted strings first, or use the Python recipe above.

”Lists nested inside mappings”

A row with containers: [{image: nginx}, {image: sidecar}] doesn’t fit a flat CSV — one row, multiple containers. The converter throws a clear error. Either explode (one row per container) via yq or project a single container’s fields.

”Indentation errors”

YAML is whitespace-sensitive — mixing tabs and spaces, or indenting children inconsistently, breaks parsing. The error message includes the line number. Most editors highlight indent issues automatically.

When YAML doesn’t fit a flat CSV

YAML is a tree. CSV is a table. The mapping works when the tree is roughly tabular — a list of similar records. It breaks down when:

  • Records have wildly different shapes — heterogeneous lists produce sparse CSVs with mostly-empty cells.
  • Nesting is deep — flattening produces 30+ columns most of which are mostly null.
  • Lists nest inside lists — there’s no obvious row boundary.

When the data really is tree-shaped, a flat CSV loses information. Two alternatives:

  1. Pre-flatten with yq to project just the fields you need (.[] | {name, status}).
  2. Convert to JSON first (yq -o=json), reshape with jq, then use the JSON to CSV tool — jq is more powerful than yq for restructuring.

Privacy: nothing is uploaded

The YAML-to-CSV conversion runs entirely in your browser. Parsing happens in a small in-house YAML reader; the CSV is generated by PapaParse. No file ever reaches a server — verify in DevTools → Network. Useful when the YAML contains secrets, internal hostnames, or any data you wouldn’t paste into a public converter.

After converting, you might want to view the CSV, go the other direction with CSV to YAML, or convert similar formats with JSON to CSV.

Related tools

Frequently asked questions

  • How do I convert YAML to CSV?

    Paste your YAML into the converter at the top of this page or upload a .yaml/.yml file. The tool flattens the top-level list of mappings into rows and writes a clean CSV. Click Download CSV or Copy to clipboard.

  • How are nested keys handled?

    Nested mappings are flattened with dot notation: a key like `metadata.namespace` becomes a single column. Inline lists (e.g. ports: [80, 443]) are kept as a JSON-stringified value inside one cell.

  • What YAML subset does this support?

    A pragmatic subset that covers config exports: top-level list of mappings (`- key: value` blocks), scalars (strings, numbers, booleans, null), one level of nested mappings, and `#` comments. Anchors/aliases, multi-document streams, and block scalars (`|`, `>`) aren't supported — convert them first with `yq` or `python -m yaml`.

  • What if my YAML doesn't fit a flat CSV?

    Some YAML — Kubernetes manifests with deeply nested specs, Ansible playbooks with task lists — doesn't map cleanly to a 2D table. The tool will either flatten one level (containers.0.image) or throw a clear error. Reshape the YAML with `yq` first if the structure is too deep.

  • Can it handle Kubernetes or Ansible exports?

    For simple list exports (e.g. `kubectl get pods -o yaml | yq '.items[] | {name: .metadata.name, status: .status.phase}'`) yes. For full multi-document Kubernetes manifests, run them through `yq` first to extract a flat list before pasting here.

  • Does it handle comments?

    Yes — `#` comments (full-line and trailing) are stripped during parsing. They don't appear in the CSV output.

  • What about quoted strings with commas?

    Quoted YAML strings (single or double) are preserved verbatim as cell values. PapaParse then re-escapes them on output per RFC 4180 — fields with commas, quotes, or newlines get wrapped in double quotes.

  • Is my YAML uploaded?

    No. Parsing and CSV generation run entirely in your browser. Your data never reaches a server. Verify in DevTools → Network.