Saltar al contenido principal

CSV to YAML

This converter turns an RFC 4180 CSV file into a YAML sequence of mappings, entirely in your browser. Column headers map to keys, and dotted or bracketed headers nest into structured YAML. The first row supplies the key names, quoting follows each format's own rules, and nothing is uploaded.

Solo local

La interfaz de esta herramienta está en inglés.

La guía de abajo solo está disponible en inglés.

CSV to YAML explained

A CSV file is a grid; a YAML file is a tree. The bridge between them is the header row: every column name is read as a path into the record it describes. A plain header like role becomes a plain key, address.city builds an address mapping with a city key inside it, and tags[0] builds a list — the same column-path convention the site's YAML to CSV converter uses, read backwards. Because the mapping is explicit and reversible, a file that goes CSV to YAML and back arrives unchanged.

The CSV side is parsed to RFC 4180: comma delimiters, double-quote escaping when a field contains a comma, quote or newline, and quoted fields that may span lines. Delimiters are sniffed from the header line — comma, semicolon, tab or pipe — counted only outside quoted regions, so a semicolon inside a description cannot hijack the guess. Type inference is deliberately narrow: only values matching the JSON number grammar become numbers, which is how a zip code like 02134 survives with its leading zero intact.

Everything runs in this browser tab. The CSV text you paste is parsed by an in-page engine, the YAML is emitted from the parsed records, and neither touches a network — open DevTools, watch the Network panel stay silent, and the claim checks itself.

Round-tripping is also the quickest correctness check, and the YAML to CSV converter rebuilds the grid from the YAML using the same column paths.

If a stubborn export refuses to parse the way you expect, the RFC 4180 field guide explains quoting, CRLF and the deviations real spreadsheet files contain.

How the conversion actually works

The engine reads the grid once and never looks at the raw text again — every later decision is made against the parsed records. That ordering is what keeps the rules composable: header paths are expanded before types are inferred, and types are inferred before the YAML emitter decides what needs quoting.

  • Parse: a small state machine splits the text into fields, honouring doubled quotes and newlines inside quoted fields, and strips a leading byte-order mark if one is present.
  • Name: the first row becomes the column names; a blank header cell falls back to column1, column2 and so on.
  • Expand: each header is decoded as a path — dots separate mapping keys, square brackets mark array indexes — and every row is rebuilt as a nested record.
  • Emit: the records are serialised as one YAML sequence, two-space indent, values quoted only when the plain form would be misread.

What the header names mean

Headers are the only place a grid can express structure, so they are read as paths rather than opaque labels. The dot and the bracket do different jobs, and the difference is what makes the mapping reversible: a dot always means a mapping key, a bracket always means an array index, so tags[0] builds a list while tags.0 builds a mapping whose key is the string 0. A converter that treated the two as interchangeable would be guessing, and the guess would be wrong half the time.

Header rowYAML produced
address.cityan address mapping with a city key inside it
tags[0], tags[1]a tags list with those two elements
tags.0a tags mapping with the string key "0" — not a list
rolea plain role key on every record

Cells, types and empty fields

Type inference exists to make the YAML useful, and it is kept on a short leash. A cell becomes a number only if it matches the JSON number grammar — which forbids leading zeros — and it becomes true, false or null only on those exact lowercase spellings. Everything else stays a string, including FALSE, +1, 0x10 and any integer longer than the safe range, where floating-point would silently drop digits. An empty cell is treated as an absent field rather than an empty value, because CSV cannot distinguish the two and the absent reading is what a sparse row almost always means.

  • 02134 stays the string "02134"; 90210 becomes the number 90210.
  • true and false become booleans; FALSE in capitals stays a string.
  • A cell with embedded newlines becomes a YAML block literal, so the line structure survives.
  • Values that would re-read as numbers are emitted with quotes, which is what keeps a round trip lossless.

Where this converter refuses to guess

Failures are reported with a line number and a reason instead of being papered over, because silent reshaping is the one failure a data tool cannot recover from. Three situations get exactly that treatment:

  • An unterminated quoted field — a double quote opened and never closed — aborts the parse at that line.
  • A row whose field count differs from the header still converts, but a warning names the affected rows and states that missing fields are treated as absent and extras dropped.
  • Duplicate column names convert with the rightmost value winning, and the warning says so — matching how a spreadsheet import behaves.

Frequently asked questions

Does converting CSV to YAML upload my file anywhere?

No. Parsing and YAML generation both run inside this browser tab with JavaScript that was loaded once when the page opened. There is no API route to send data to, and the page's Content-Security-Policy sets connect-src 'self', so the browser itself would refuse any outbound request. You can verify both claims in DevTools: the Network panel shows no request when you convert.

How do CSV headers become nested YAML keys?

Each header is decoded as a path: dots separate mapping keys and square brackets mark array indexes, so address.city nests under an address key while tags[0] builds a list. The bracket form is not decoration — tags.0 instead creates a mapping with the string key "0", because a bare dot cannot say whether the level below is a list or an object. Keeping the two spellings distinct is what makes the convention reversible.

What happens to numbers and zip codes in the cells?

A cell becomes a number only when it matches the JSON number grammar, which forbids leading zeros — so 02134 stays a string while 90210 becomes a number. Integers beyond the safe range also stay strings rather than losing digits. Booleans require the exact lowercase spellings true and false, and null likewise; FALSE in capitals remains the string it visibly is.

Why do empty cells disappear from the YAML output?

An empty cell is emitted as an absent key, not an empty value. CSV has no way to distinguish a field that is genuinely empty from one a row simply does not have, and the absent reading matches the sparse case that actually occurs — a record shorter than the widest row. If a downstream consumer needs the key present, an explicit quoted empty cell is the way to ask for it.

What indentation style does the YAML output use?

Two spaces per level, the convention used across Kubernetes, CI and Docker files, with sequence dashes aligned to their parent key rather than indented under it. Multi-line cells become block literals so embedded line breaks survive verbatim, and the document is emitted without a leading --- marker because a single-document file does not need one.

How large a CSV file can this handle?

The practical limit is this tab's memory, not an upload cap — the paste box is the input. Like every main-thread tool on this site there is a documented 8 MB ceiling; above it, processing is refused with a clear message rather than freezing the page. For typical tabular exports that headroom is tens of thousands of rows.