Flatten nested JSON
Runs locallyCollapse nested objects into a single level of dot-notation keys.
JSON input
Result
Dot notation, and the two cases where it cannot round-trip
Flattening turns a nested document into a single level of key-value pairs, with the path to each leaf joined by dots. It is how you get a JSON config into environment variables, how you turn an API response into CSV columns, and how you make two payloads diffable line by line instead of block by block. For CSV specifically, the JSON to CSV converter flattens every record and writes the columns in one step.
The operation is lossy in two specific ways, and both bite when you try to unflatten the keys back into JSON afterwards.
Nested
{
"service": {
"name": "shop-api",
"ports": [8080, 8443],
"limits": { "cpu": "500m" }
},
"tags": [],
"labels": { "app.kubernetes.io/name": "shop" }
}Flattened
{
"service.name": "shop-api",
"service.ports.0": 8080,
"service.ports.1": 8443,
"service.limits.cpu": "500m",
"labels.app.kubernetes.io/name": "shop"
}Note what happened to the last two keys: "tags": [] produced nothing at all, and the Kubernetes-style label key already contained dots, so its flattened form is indistinguishable from three levels of nesting.
Where people get caught
A key that already contains a dot becomes ambiguous
{"a.b": 1} and {"a": {"b": 1}} both flatten to "a.b". Nothing downstream can tell them apart, so unflattening picks one and silently changes your data. Kubernetes labels, DNS names and file names hit this constantly — use a separator your keys cannot contain.
Empty arrays and empty objects disappear
There is no leaf under them, so there is no pair to emit. If the difference between "absent" and "present but empty" matters — and in a config diff it usually does — keep them as an explicit sentinel value.
Array indices become plain keys
items.0, items.1 are strings, not positions. Delete the middle element of a flattened array and unflattening either leaves a hole or produces an object with numeric keys, depending on the implementation.
Numeric object keys turn into array slots
A map keyed by year — {"2024": …, "2025": …} — unflattens into a sparse array in naive implementations, because the key looks like an index. Check the round-trip before you rely on it.
Flatten then unflatten is not guaranteed to be the identity
Given the four points above, treat the round-trip as something to verify rather than assume. If you are using flattening as a transport format, compare the rebuilt document against the original once, on a real payload with real keys.
About flattening nested JSON
How it works in 4 steps · 4 common use cases · 3 questions answered
About flattening nested JSON
How it works in 4 steps · 4 common use cases · 3 questions answered
How it works
- 1.Paste a nested JSON document.
- 2.Every leaf value is rewritten as a single key describing its full path, joined with dots.
- 3.Array positions are kept as bracketed indexes, so a.b[0].c stays unambiguous.
- 4.Copy the flat result, or feed it into the unflattener to get the original back.
Common use cases
- •Turning a nested config tree into flat keys for environment variables or a properties file
- •Diffing two deeply nested documents line by line instead of block by block
- •Preparing a JSON document for a CSV export where every leaf needs its own column
- •Building a checklist of every path in a payload before writing extraction code
FAQ
What separator is used?
A dot between object keys and square brackets for array indexes — the same notation JSONPath and most config libraries use, so the output is usually directly reusable.
What happens to a key that already contains a dot?
It is kept as written, which makes that one path ambiguous when read back. If your keys contain dots, flattening is a lossy step for them.
Is flattening reversible?
Yes, for documents without dots inside key names. Run the result through the JSON Unflattener and you get the original structure back.