JSON vs YAML vs CSV
Three formats dominate data interchange, and the choice between them is not about superiority — it is about matching structure, consumers, and failure modes. This comparison makes the trade-offs concrete.
Data models: what each format can express
JSON models data as nested objects and arrays with typed values — strings, numbers, booleans, null. Its expressiveness covers most structured data directly, and its syntax is small enough that every developer already knows it. YAML is a superset in expressive power: mappings, sequences, scalars, plus multi-document files, anchors for repeated structures, and readable multi-line strings — at the cost of a specification deep enough to surprise anyone who assumes it is 'just indented JSON'.
CSV models something fundamentally different: flat records. A header row names columns; each subsequent row is one record of positional fields. There is no nesting, no per-value types — everything is text until a consumer decides otherwise — and no structure beyond the table. The comparison's first rule follows immediately: nested or typed data belongs in JSON or YAML; tabular data where every record has the same shape belongs in CSV. The formats are not competitors across the board — they are specialists whose territories overlap only in the flat, simple middle.
Human readability and the edit-in-place question
YAML was designed for human eyes and shows it: minimal punctuation, indentation as structure, comments supported natively — the only format of the three you can annotate in place. Configuration files that humans maintain by hand are YAML's home territory precisely because editing them does not require syntactic ceremony. JSON is readable enough for small structures but hostile to hand-editing at scale: no comments, quote-and-comma discipline everywhere, and every manual edit risks a syntax error the format will not forgive.
CSV is the extreme case: perfectly readable as a table, unreadable as anything else. Editing a CSV row is trivial in a spreadsheet and error-prone by hand the moment a field contains a comma or quote — the escaping rules that make CSV machine-friendly make it treacherous for manual surgery. The decision heuristic: who touches this file with their hands? If the answer is 'developers editing configuration', YAML. If 'nobody, it is generated', JSON. If 'analysts in a spreadsheet', CSV. Readability is not a style preference; it is a maintenance cost prediction.
Types, parsing surprises, and safety
JSON's type system is explicit and boring — values declare what they are — which is why it parses identically everywhere. YAML's type inference is where surprises live: unquoted values are interpreted, so yes becomes a boolean, 3.10 becomes 3.1, and country codes like NO become false. The famous YAML gotchas are not bugs but inference working as specified, which makes them worse — they are documented behavior that still ambushes. The defensive habit in YAML: quote anything that should survive as a string, especially values resembling booleans, numbers, or version strings.
CSV carries no types at all — every field is text, and consumers guess: the leading-zero zip code that becomes 01234, the number that becomes scientific notation, the date that re-formats itself. Each consumer applies its own inference, so the same CSV means different things in different tools. The safety hierarchy for data whose types matter: JSON's explicitness first, YAML with disciplined quoting second, CSV with a documented schema third. Type surprises are the cheapest errors to make and the most expensive to find downstream.
Interoperability: who consumes what
JSON is the interchange lingua franca: every language parses it, every API speaks it, and conversion from either other format into JSON is a solved problem. When the consumer set is unknown — a public API, a data export for strangers — JSON is the default that maximizes compatibility. CSV owns a different interchange niche: spreadsheets, data tools, and anything tabular, where its flat simplicity is the feature — every analysis tool imports CSV natively, and exports to it are universal.
YAML's interchange role is narrower and more specific: configuration ecosystems — container orchestration, CI pipelines, package managers — where its readability and comments serve human maintainers. Sending YAML to consumers outside that ecosystem is a compatibility risk: parser quality varies, and the inference surprises travel with the file. The practical matrix: API payloads and web interchange, JSON; tabular exchange with analysts and tools, CSV; human-maintained configuration inside supporting ecosystems, YAML. Each format's dominance is real but bounded; the mistake is exporting a format's home-turf strengths to foreign contexts.
Diffs, streaming, and operational concerns
Operational properties separate the formats as sharply as syntax does. Line-based diffs favor JSON with one-key-per-line formatting and YAML naturally — changes land at readable positions. CSV diffs work for flat changes but reflow badly: one inserted field shifts every subsequent line, turning a one-change diff into a whole-file change. Version control on any of these rewards format-aware habits; CSV in source control is the weakest fit of all.
Streaming separates them more decisively. JSON and CSV both stream record-by-record reasonably — line-delimited JSON is the standard for feeds, and CSV is inherently row-streaming. YAML streams poorly: anchors and multi-document structure want the whole file in view. Size behavior: CSV is the most compact for flat data; JSON carries structural overhead per value; YAML sits between but grows with indentation. The operational summary: feeds and logs, line-delimited JSON; bulk tabular transfer, CSV; anything requiring mid-file relationships or anchors, YAML with the understanding that it processes whole-file. Match the format to the pipeline's shape, not just the data's.
The decision matrix and conversion realities
The compressed decision table. Shape: nested or typed, JSON or YAML; flat and uniform, CSV. Maintenance: hand-edited by humans, YAML; generated and consumed by machines, JSON; spreadsheet-bound, CSV. Consumers: unknown or public, JSON; tabular-analysis ecosystem, CSV; configuration ecosystems, YAML. Types matter and surprises must be minimized: JSON first. Comments needed in the file itself: only YAML provides them.
Conversion between the three is routine but lossy in characteristic directions. JSON to YAML reads better but gains inference risk; YAML to JSON loses comments and anchors; either to CSV flattens — nested structures must be denormalized by explicit rules, or the nesting is silently lost; CSV to JSON gains types only by explicit schema, since the source carries none. The professional discipline: choose the format at the origin, convert at boundaries deliberately with the losses named, and never treat conversion as free. Formats are contracts with every consumer downstream; the matrix exists so the contract is chosen knowingly rather than inherited by accident.
Moving data between the three
Real projects rarely pick one format forever; they migrate, and the migration patterns are worth knowing. CSV to JSON is the classic ingestion move: flat records become structured objects, ready for nested processing — with the conversion forcing decisions CSV deferred, like which columns are numbers and which are strings. JSON to CSV is the reporting move: structured data flattened for spreadsheet audiences, with nested fields resolved by convention — flattened keys or dropped depth — because spreadsheets have no second level.
YAML sits between the two as the human-editing bridge: configurations authored by hand prefer its readability, then convert to JSON for machines at the boundary. The migration rule that prevents corruption: convert at system boundaries, never mid-storage. A configuration stored as YAML and converted to JSON at deployment keeps authoring pleasant and consumption precise; the same configuration hand-edited in both formats drifts inevitably. One representation is canonical; the others are generated views.
Schema awareness survives migration only if carried deliberately. CSV carries no types, so conversions into typed formats need explicit decisions or they inherit surprises — postal codes becoming numbers, identifiers gaining decimals. JSON to YAML conversions preserve structure but can introduce ambiguity around strings that look like other types. The professional practice: validate after every migration, sample-inspect the converted output, and keep the canonical source authoritative. Formats are dialects of the same data; migration is translation, and like all translation it deserves a review pass before anyone trusts the result.
Frequently asked questions
Which format should I use for configuration files?
YAML when humans maintain the file and the ecosystem supports it — comments and readability matter there. JSON when machines generate and consume it.
Why does YAML turn my values into booleans?
Type inference: unquoted yes, no, and similar values are interpreted, not preserved. Quote anything that must remain a string.
Is CSV good enough for data with nested structure?
No — CSV is flat by nature. Nested data needs JSON or YAML, or explicit flattening rules with the losses documented.
Which format is smallest?
CSV for flat data; JSON's structural overhead grows with nesting. But size rarely outweighs compatibility and type safety in the decision.
Can I convert JSON to CSV losslessly?
Only if the JSON is flat. Nested objects and arrays require denormalization rules — conversion flattens or fails, never silently preserves.
Which format for API responses?
JSON — universal parsing, explicit types, and streaming support make it the interchange standard.
Do these formats support comments?
YAML natively. JSON does not — comments are a syntax error. CSV has no standard comment mechanism.
Why do spreadsheets mangle my CSV?
CSV carries no types, so consumers infer: leading zeros vanish, dates reformat, numbers go scientific. Document the schema or deliver typed formats.
How do I convert CSV data to JSON?
Each row becomes an object with column-name keys. Decide types deliberately during conversion — CSV carries none, so numbers, strings, and booleans need explicit assignment.
Can I keep a config in YAML and serve it as JSON?
Yes — author in YAML, convert at the boundary, and keep the YAML as the single canonical source. Hand-editing both formats guarantees drift.