JSON Flatten and Unflatten
Flatten nested JSON into single-level keys like user.tags[0], or unflatten them back. Choose the separator and array style. Runs in your browser, no upload.
Worked examples
- Flatten nested objects and arrays
Each leaf value ends up on one line keyed by its full path, with array positions written as [0], [1], the style lodash and many config libraries use.
- Flatten with a slash separator and dotted indexes
Environment-variable and path-style key schemes need a different separator; empty objects and null are kept as leaf values so no data is lost.
- Unflatten dotted keys back into nested JSON
Going the other way: the key paths are split on the separator and [n] segments become array positions, rebuilding the original structure.
What this does
Flattening turns nested JSON into a single-level object whose keys are the paths to each value. {"user":{"tags":["a","b"]}} becomes {"user.tags[0]":"a","user.tags[1]":"b"}. Unflattening reverses it, rebuilding the nested structure from the paths. Use the mode switch to go either way. Everything runs in your browser.
How it works
Flatten walks the document depth-first and records each leaf value under its full path. Object keys are joined with the separator you choose (a dot by default, up to five characters), and array positions are written in one of two styles:
- Bracket style writes
tags[0]andhosts[1].port. This is the style used by lodash, many form libraries and the JavaScript expression you would type by hand. - Dotted style writes
tags.0andhosts.1.port. This is the form many configuration systems, logging tools and search indexes expect.
Leaves are scalars, null, and empty containers: an empty object stays {} and an empty array stays [], so no information is lost.
Unflatten splits each key back into segments and creates objects and arrays on the way down. In bracket style, [n] segments are array indexes and everything else is an object key. In dotted style the tool has to guess, because a.0 could mean the key "0" or the first element. It assumes that a segment made only of digits, with no leading zero, is an array index.
The round-trip trap
Flatten and unflatten are exact inverses only when no original key contains the separator. A key like "a.b" flattens to a.b, which unflattens into {"a":{"b":…}}. The tool detects such keys (and, in bracket style, keys with square brackets) and adds a note. If two different paths would produce the same flat key, for instance {"a.b":1} beside {"a":{"b":2}}, flattening stops with an error rather than overwriting one value with the other. The fix is to pick a separator that does not appear in your keys, such as / or ::.
Edge cases and limits
- The top level must be an object or an array to flatten. An empty top-level object flattens to
{}. - Top-level arrays flatten to keys like
[0].namein bracket style and0.namein dotted style, and unflatten back to an array when the first key starts with an index. - Gaps in array indexes become
null, since a JSON array cannot have holes:items[2]alone yields[null, null, value]. Indexes above 100,000 are rejected so a typo cannot allocate a giant array. - Conflicts such as
{"a":1,"a.b":2}fail with a message naming the key that is both a value and a parent. - Key order follows the input, and the unflattened result keeps first-seen order. The one exception is keys that are whole numbers, such as
"2"or"10": JavaScript always lists those first, in ascending order, in any object it writes out. - Output indentation is adjustable; set it to 0 for one compact line.
- Numbers pass through JavaScript parsing, so integers above about 9 × 10^15 lose precision, as in any browser JSON tool.
When to use it
- Preparing nested API data for CSV or a spreadsheet, where each column needs a single key.
- Diffing two configuration trees: one flat line per value makes changes obvious.
- Mapping nested config to environment variables or to key-value stores such as Consul or etcd.
- Rebuilding nested config from a flat set of properties, for instance from a Java
.propertiesstyle or a form submission.
After flattening, the JSON to CSV tool can turn an array of flat records into rows, and the JSON Diff tool can compare two documents structurally.
Frequently asked questions
- How are arrays written in the flattened keys?
- In bracket style an array element is [index] appended to its parent, as in tags[0] or hosts[1].port. In dotted style the index is just another segment, as in tags.0 or hosts.1.port. Bracket style is unambiguous when unflattening; dotted style has to guess that all-digit segments are array indexes.
- What happens to empty objects and empty arrays?
- They are kept as leaf values ({} and []), because dropping them would lose information. Unflattening turns those leaves back into empty containers, so the round trip is lossless for them as well.
- Can flatten and unflatten always round-trip?
- Not always. If an original key contains the separator (such as "a.b") or, in bracket style, a square bracket, the flat key is ambiguous and unflattening will split it into nested keys. The tool flags this in the notes. Two paths that produce the same flat key, for example {"a.b":1} next to {"a":{"b":2}}, stop the conversion with an error rather than overwriting a value.
- What happens with missing array indexes when unflattening?
- Gaps are filled with null, because JSON arrays cannot have holes. A key like items[2] on its own becomes [null, null, value]. Indexes above 100,000 are rejected to protect your browser from a huge array.