How to use the json unflatten
- Paste your flat JSON object into the Flat JSON input box.
- Set the Key separator if your keys use something other than a dot (for example
/). - Adjust Indent spaces to control how the output is formatted.
- The nested JSON result appears automatically as you type.
How JSON unflattening works
A flat JSON object stores every value at the top level using compound keys. To json unflatten it, each key is split by the separator into an ordered list of segments. The algorithm walks through those segments one by one, creating nested objects along the way, and assigns the value at the final segment.
For example, given the key user.address.city with value "NYC", the process creates {}, then { user: {} }, then { user: { address: {} } }, and finally sets { user: { address: { city: "NYC" } } }. When multiple keys share a prefix they write into the same branch rather than overwriting it.
Detecting arrays from numeric keys
When every key at a given nesting level is a non-negative integer with no gaps or leading zeros, the result is built as a JSON array instead of an object. For instance, the flat keys "0", "1" and "2" produce [val0, val1, val2].
Bracket indexes written by the JSON flatten tool, such as items[0].id, are understood as well, so flatten and unflatten round-trip. This detection happens independently at each depth. You can have an object that contains an array which in turn contains objects. If even one sibling key at a level is not a valid array index, the entire level becomes an object and the numeric strings remain ordinary property names.
Common flat JSON patterns
Several tools and APIs emit flattened JSON. Here are typical patterns you might need to json unflatten:
| Pattern | Example flat key | Nested result |
|---|---|---|
| Dot notation | a.b.c | {"a":{"b":{"c":...}}} |
| Slash paths | config/db/host | {"config":{"db":{"host":...}}} |
| Array indices | users.0.name | {"users":[{"name":...}]} |
| Mixed depth | x and y.z | {"x":...,"y":{"z":...}} |
The separator field lets you handle any of these conventions without editing the source data first.
Edge cases and conflicts
Not every flat object can be converted cleanly. A conflict occurs when one key treats a path segment as a final value while another key tries to nest properties inside it. For example, {"a": 1, "a.b": 2} is contradictory because a cannot simultaneously hold the number 1 and be an object containing b. This tool reports such conflicts as errors instead of silently discarding data.
Empty keys, empty separators and trailing separators also cause problems. An empty separator would split every key into individual characters, which is almost never intended. Always verify that the separator matches exactly what was used when the JSON was flattened.
Worked examples
| Example | Input | Result |
|---|---|---|
| Simple user object | Flat JSON input: {"user.name":"Alice","user.age":30,"active":true}; Key separator: .; Indent spaces: 2 | { / "user": { / "name": "Alice", / "age": 30 / }, / "active": true / } |
| Array indices | Flat JSON input: {"items.0.id":1,"items.0.name":"Widget","items.1.id":2,"items.1.name":"Gadget"}; Key separator: .; Indent spaces: 2 | { / "items": [ / { / "id": 1, / "name": "Widget" / }, / { / "id": 2, / "name": "Gadget" / } / ] / } |
| Custom separator | Flat JSON input: {"app/config/host":"localhost","app/config/port":8080}; Key separator: /; Indent spaces: 2 | { / "app": { / "config": { / "host": "localhost", / "port": 8080 / } / } / } |
FAQ
What does it mean to json unflatten an object?
It means converting a single-level JSON object whose keys encode a path (like "a.b.c") back into a deeply nested structure where "a" contains "b" which contains "c".
Can I use a separator other than a dot?
Yes. Change the Key separator field to any string, such as "/" or "::", and the tool will split keys on that exact sequence.
How are arrays handled?
If all sibling keys at a certain depth are consecutive non-negative integers starting from zero, the tool builds a JSON array at that level instead of an object.
Is my data sent to a server?
No. Parsing and restructuring happen entirely in your browser. Nothing is uploaded anywhere.
Why do I get a conflict error?
A conflict happens when one key assigns a primitive value to a path and another key tries to add children under the same path. For example, {"a":1} and {"a.b":2} cannot coexist.
Does it preserve Unicode characters?
Yes. All string values and key segments retain their original Unicode content, including emoji and non-Latin scripts.