Skip to content
LocalOnly

JSON Unflattener

Stable

Rebuild nested JSON from flat dot-notation keys.

Everything is processed locally in your browser

About JSON Unflattener

The JSON Unflattener is the inverse of flattening: it reads an object of dot-notation keys and reconstructs the full nested structure they describe. Numeric path segments are rebuilt as arrays, and everything else becomes nested objects. It is the fastest way to turn a flat config map or spreadsheet export back into structured JSON.

Features

  • Rebuilds deeply nested objects from dotted key paths
  • Reconstructs arrays from numeric path segments like items.0.sku
  • Supports custom delimiters to match how the data was flattened
  • Preserves the original type of every leaf value
  • Detects conflicting paths and reports them clearly
  • Round-trips with the JSON Flattener to restore the exact structure

How to use JSON Unflattener

  1. 1

    Paste flat JSON

    Provide an object whose keys are dot-notation paths, such as user.address.city.

  2. 2

    Match the delimiter

    Set the same separator that was used when the data was flattened.

  3. 3

    Unflatten

    The tool expands the flat keys into a fully nested object and array structure.

  4. 4

    Copy the nested JSON

    Use the reconstructed document in your app, API, or config.

Examples

Dot-notation keys to nested JSON

Input

{
  "user.name": "Mira",
  "user.roles.0": "admin",
  "user.roles.1": "editor"
}

Output

{
  "user": {
    "name": "Mira",
    "roles": ["admin", "editor"]
  }
}

How unflattening JSON works

Rebuilding a tree from path strings

Unflattening reads each dotted key as a route and creates the containers along the way. Given `user.address.city`, it makes a `user` object, an `address` object inside it, and finally sets `city` to the leaf value. Process every key in the flat map this way and the original nested structure reassembles itself.

The decision the algorithm makes at each step is whether to create an object or an array, and it uses the notation to decide. A bracketed numeric segment like `items[0]` means the parent must be an array; a plain segment like `items.first` means it must be an object. This is why the bracket convention matters rather than being cosmetic - it is the only signal available about what kind of container to build.

Where flat data comes from in the first place

Spreadsheets are the biggest source. A CSV exported from a system that had nested data will have columns named `customer.email` and `items[0].sku`, because that is the only way a flat format can carry structure. Unflattening turns those columns back into the shape an API expects.

Configuration and environment variables are the second. Systems that flatten config into `DATABASE__HOST` or `app.database.host` need the reverse operation before the values can be handed to something that wants a nested object.

Form libraries are the third. Many keep their state as a flat map keyed by field path, because that makes per-field validation and dirty-tracking simple. Submitting to an API usually means rebuilding the nested payload first.

The ambiguities the tool has to resolve

Flat keys carry less information than the tree they describe, so some inputs are genuinely ambiguous and the reconstruction has to pick a rule. Conflicting types are the clearest case: if the map contains both `a` and `a.b`, then `a` needs to be a scalar and an object at once. That cannot be satisfied, and the later key wins.

Gapped array indices are the second. `items[0]` and `items[2]` with nothing at `items[1]` could mean an array with a hole, or an object with numeric-looking keys. Filling the gap with null is the usual choice, but it is a choice rather than a recovery of what was there.

Keys containing literal dots are the third and the most common in practice. There is no way to tell `{"a.b": 1}` (one key with a dot) from `{"a": {"b": 1}}` (two levels) once flattened, so the nested interpretation is always taken.

Reference

How path segments are interpreted

Flat keyRebuilds asRule applied
"a.b": 1{"a":{"b":1}}Plain segment creates an object
"a[0]": 1{"a":[1]}Bracketed index creates an array
"a[0].b": 1{"a":[{"b":1}]}Mixed segments nest objects inside arrays
"a[2]": 1 only{"a":[null,null,1]}Gaps are filled with null to preserve position
"a": 1 and "a.b": 2{"a":{"b":2}}Type conflict: the object interpretation wins

Which tool should you use?

These tasks overlap. Here is how to pick the right one for what you are actually doing.

You have spreadsheet columns like `user.name` to turn into JSON
The CSV to JSON tool handles the parse and the unflattening together, which is fewer steps than doing each separately.
You already have a flat JSON object of dotted keys
This is the right tool - paste it and get the nested structure back.
You are going the other direction, nested to flat
The JSON Flatten tool is the inverse and uses the same notation.
Your flat keys use a separator other than a dot
Replace your separator with a dot first. Double underscores from environment variables are the usual case.

Use cases

  • Restoring structured JSON from a spreadsheet exported as flat columns
  • Turning flat environment-style keys back into a config object
  • Rebuilding nested payloads from a key-value store
  • Reassembling translation files stored as dotted paths
  • Completing a flatten-edit-unflatten workflow on nested data

Troubleshooting common errors

An array came back as an object with keys "0", "1"

Why: The keys used dot notation for indices (`items.0`) rather than brackets, so there was no signal that an array was intended.

Fix: Rewrite the keys as `items[0]`. Bracket notation is what distinguishes an index from an object key.

Nulls appeared in an array that had no nulls

Why: The indices had gaps, and positions must be filled to keep the remaining elements at their stated indices.

Fix: Supply a contiguous index sequence starting at 0, or strip the nulls after unflattening.

A value was overwritten by another key

Why: Two keys implied incompatible types at the same path, such as `a` as a scalar and `a.b` as an object.

Fix: Resolve the collision in the flat data. Two keys cannot occupy one path in the reconstructed tree.

A key that legitimately contained a dot got split apart

Why: Dots are always treated as separators - there is no escaping convention that would let a literal dot survive.

Fix: Rename the key upstream to remove the dot. This is a genuine limitation of dotted-path notation, not of this implementation.

Limitations

What this tool deliberately does not do, so you know when to reach for something else.

  • Dots are always separators; a key containing a literal dot cannot be represented.
  • Only bracket notation signals an array. Numeric object keys stay object keys.
  • Gaps in array indices are filled with null, which may not match the original.
  • Conflicting paths resolve by last-write-wins rather than raising an error.
  • Empty objects and arrays cannot be reconstructed, because a flat map has no way to record them.

Frequently asked questions

Learn more

Command Palette

Search for a tool or command