# How to Flatten Nested JSON to Dot-Notation Keys (and Back)

URL: https://pdfflare.com/blog/flatten-nested-json
Published: May 1, 2026
Reading time: 8 min read

> Flatten nested JSON to dot-notation keys free online. Convert to flat, env-var, or path style — unflatten back round-trip safe. Browser-based, no signup.

---

You're wiring up a React form with React Hook Form and the field paths it expects look like `user.address.city`, not the nested object you've got. Or you need to feed a config to a 12-factor app and the env vars want flat keys like `DATABASE_HOST`, not nested JSON. Or you're managing translations and your i18n library wants dot keys. All three problems have the same fix: flatten the nested JSON.

In this guide you'll learn how to flatten nested JSON to dot-notation keys (and unflatten back) using [PDFFlare's JSON Flatten tool](https://pdfflare.com/tools/json/json-flatten) — with delimiter options for env-var, path-style, and custom formats. 100% browser-based, round-trip safe.

## What Does Flattening JSON Mean?

Flattening collapses a nested JSON document into a single-level object whose keys describe the path to each leaf value. The structure becomes part of the key, not the shape:

**Nested:** `{ "user": { "name": "alice", "address": { "city": "NYC" } } }`

**Flat (dot delimiter):** `{ "user.name": "alice", "user.address.city": "NYC" }`

Arrays use bracket-index notation: `{ "tags": ["a", "b"] }` becomes `{ "tags[0]": "a", "tags[1]": "b" }`.

Unflattening is the reverse — take a flat dot-keyed object and rebuild the nested structure. Round-trip safe for the typical case.

## Why Flatten Nested JSON?

- **Form data libraries:** React Hook Form, Formik, and most form libs use flat path strings as field names. Flattening is the bridge between your domain model and the form layer.
- **Environment variables:** 12-factor apps consume config as flat env vars. Convert nested config to flat with` _ ` as the delimiter, set in your environment, parse back at startup.
- **Translation files:** i18n libraries (i18next, react-intl) typically use dot keys. Authors write nested JSON for readability, the build flattens for runtime lookup.
- **Flat key-value stores:** Redis, etcd, Consul KV — all flat. Flatten your config, store as flat keys, no nested structure to manage.
- **Spreadsheet exports:**CSV is flat; nested JSON doesn't map cleanly. Flatten first, convert via [JSON to CSV](https://pdfflare.com/tools/json/json-to-csv), import to Excel.
- **Logging and analytics:** Many log indexers prefer flat key paths over deep nesting. Flatten before sending to keep search performant.

## How to Flatten JSON (Step by Step)

1. **Open [PDFFlare's JSON Flatten tool](https://pdfflare.com/tools/json/json-flatten)** — no signup.
2. **Make sure direction is set to Flatten** (the default).
3. **Pick a delimiter.** Dot (`.`) is default; switch to underscore for env-var-style, slash for path-style, or Custom for anything else.
4. **Paste your nested JSON** into the input pane.
5. **Click Convert.** The output pane shows the flattened object with one entry per leaf.
6. **Copy or download.** To go back: toggle direction to Unflatten, paste the flat object, click Convert. The Swap button moves output to input for round-tripping.

## Delimiter Options Explained

- **Dot (`.`) — the default.** The most common style. Works with React Hook Form, Lodash `_.get`, JSONPath, and most i18n libraries.
- **Underscore (`_`) — env-var style.** `{ "database": { "host": "localhost" } }` becomes` { "database_host": "localhost" }` — convert to uppercase and set as env var `DATABASE_HOST`.
- **Slash (`/`) — path style.** Useful for JSON Pointer-like keys, Consul KV (which uses slash by convention), or any system that treats paths hierarchically.
- **Custom — anything you want.** Type any string into the custom field. Common choices: `__` (double underscore for env vars that contain single underscores), or` ::` (double colon).

## Round-Trip Safety

Flatten then unflatten should reproduce the original JSON exactly. PDFFlare's tool handles the typical case faithfully:

- **Nested objects:** Reconstructed exactly.
- **Arrays:** Index-based paths preserve element order and length.
- **Scalar values:** Strings, numbers, booleans, null — all preserved as-is.
- **Empty objects and arrays:** Preserved as a single entry at their path so unflatten can rebuild them.

## Handling Keys That Contain the Delimiter

If a key contains the active delimiter, flattening would create ambiguity — is `a.b` the path to `b` inside` a`, or a single key literally named `a.b`? PDFFlare's flatten tool wraps such keys in` ["..."]` so the round trip stays unambiguous:

**Input:** `{ "a.b": 1 }` (with dot delimiter active)

**Flat output:** `{ "[\"a.b\"]": 1 }`

Unflatten reads the bracket-quoted segment as a single key, restoring the original. Works for slashes, underscores, custom delimiters too.

## Common Scenarios

### React Hook Form Field Paths

Your domain model is `{ user: { profile: { firstName: '' } } }`. React Hook Form's field name is `user.profile.firstName`. Flatten the model on read, unflatten on submit. Same data, two representations.

### Helm Chart `--set` Flags

`helm install --set app.replicas=3 --set app.image.tag=latest` is equivalent to a small nested values.yaml. If you start with the nested form, flatten with dot delimiter to produce `--set` flags directly.

### i18n Translation Keys

Authors write `{ "home": { "hero": { "title": "Welcome" } } }` for readability. The runtime library wants flat keys like` home.hero.title`. Flatten as a build step.

### 12-Factor App Configs

Maintain config as nested JSON (easy to read), flatten with `_` delimiter for env vars, set in your container, unflatten at startup. Best of both worlds.

### Spreadsheet Exports

Need to share a nested API response with a spreadsheet user? Flatten first (so each leaf becomes its own column), then convert via [JSON to CSV](https://pdfflare.com/tools/json/json-to-csv). Excel handles the result cleanly.

### Database Migration Diff

Flatten the old and new schemas, then run them through [JSON Diff](https://pdfflare.com/tools/json/json-diff). The flat form makes structural changes pop.

## Lodash, Ramda, and Friends: When You Don't Need to Flatten

Flattening physically reshapes your data. Sometimes you don't need that — you just need to read or write a value at a path. Path-aware accessor libraries handle this without flattening:

- **Lodash `_.get` and `_.set`:** `_.get(obj, "a.b.c", defaultValue)` reads a nested value by a dot path; `_.set` writes one (creating missing intermediate objects). No flattening needed.
- **Ramda `R.path`:** Functional alternative with array-of-keys instead of dot strings: `R.path(["a", "b", "c"], obj)`. Curryable, easy to compose.
- **Native optional chaining:** Modern JS supports` obj?.a?.b?.c` for safe navigation. No library at all, just language. Best for known-shape access.

Rule of thumb: flatten when downstream needs flat keys (forms, env vars, key-value stores). Use accessor libraries when your code needs to read or write paths but the data stays nested.

## Performance: When to Flatten and When Not To

Flattening allocates a new object roughly the size of every leaf in the source. For typical configs and API responses this is fine. A few cases where it matters:

- **Small documents (under ~10 KB):** Flatten freely. Performance cost is negligible.
- **Medium documents (10 KB - 1 MB):**Flatten on demand, not on every call. Cache the flat form if you'll access it repeatedly.
- **Large documents (above ~10 MB):** Flattening doubles memory use during the transformation. Use Lodash `_.get(obj, 'a.b.c')` on the nested form for individual lookups instead — same path syntax, no allocation.
- **Streaming data:**Don't flatten. Use a streaming JSON parser and a path-aware visitor instead. PDFFlare's tool isn't designed for streaming.

## Common Mistakes

- **Choosing a delimiter that appears in your keys.** If your keys contain dots and you flatten with dot delimiter, you'll either get bracket-quoted segments (PDFFlare's behaviour) or ambiguous paths (other tools). Pick a delimiter that doesn't collide with key content.
- **Unflatten in a different tool with a different delimiter convention.** If you flatten with dot in PDFFlare and try to unflatten in another library configured for slashes, nothing unflattens. Round-trip in the same tool, or document the delimiter choice clearly.
- **Forgetting that arrays use bracket-index, not dot-index.** `tags[0]`, not `tags.0`. PDFFlare follows the standard convention; some libraries differ.
- **Treating flatten as lossless for streaming data.** Flatten on a 100-MB log file produces an even bigger flat object. Streaming flatten is a different tool — for huge data, use a scripting language with a streaming JSON parser.
- **Mixing delimiters within one document.**One document, one delimiter. Mixing means unflatten can't parse the result correctly.

## Best Practices

- **Pick a delimiter and document it.**A README note saying “all flat configs use dot delimiter” saves future-you confusion.
- **Flatten as a build step, not at runtime.** Translation files, env-var configs — generate the flat form once during build, ship the flat form, save runtime parsing cost.
- **Use Dot Notation libraries on flat data.** Lodash `_.get(obj, "a.b.c")`works on the nested form too — sometimes you don't need to flatten, you just need a path-aware getter.
- **Validate flat input keys against expectations.** If you're consuming flat input from an external source, validate that all expected paths are present — typos in flat keys silently produce missing values.

## Flatten vs JSON Pointer vs JSONPath

Three ways to address values inside a JSON document. They look similar, but solve different problems:

- **Flatten (this tool):** Materializes every leaf path as a key. Output is a new flat JSON object. Best for handing data to systems that natively expect flat keys.
- **JSON Pointer (RFC 6901):** A path syntax (`/user/address/city`) used for `$ref`in JSON Schema and OpenAPI. Doesn't flatten — just describes “where in the document.” Tools use it to resolve specific values.
- **JSONPath:** A query language, not a flatten operation. `$.user.address.city` looks similar to a flat key, but you use it to _extract_values, not to re-shape the document. See PDFFlare's [JSONPath Tester](https://pdfflare.com/tools/json/json-path).

Rule of thumb: flatten when you need a new flat document; JSONPath when you need to query an existing nested document; JSON Pointer when you're writing schema $refs.

## Edge Cases Worth Testing

- **Mixed-type arrays:** Flattening `{"items": [1, "two", {"a": 3}]}` produces three entries with different value types — `items[0]: 1`, `items[1]: "two"`, `items[2].a: 3`. Round-trip safe.
- **Nested arrays:** `{"matrix": [[1,2],[3,4]]}` flattens to four entries with bracket-bracket paths like `matrix[0][0]`.
- **Boolean and null leaves:** Preserved as their actual values, not stringified.
- **Numeric string keys:** A key like `{"42": "answer"}` stays a string key in the flat output — JSON object keys are always strings.

## Privacy: Your JSON Stays on Your Device

PDFFlare's JSON Flatten runs entirely in your browser. The flatten and unflatten logic is JavaScript executed locally — your JSON never uploads anywhere. Safe for production configs containing secrets, customer data, or anything sensitive.

## Wrapping Up

Flat dot-notation is the lowest-common-denominator format for consuming nested data — works in form libraries, env vars, key-value stores, translation files, and spreadsheets. A solid bi-directional flatten/unflatten with delimiter options handles 95% of the cases you'll hit.

Got nested JSON that needs to land somewhere flat? Open [PDFFlare's JSON Flatten tool](https://pdfflare.com/tools/json/json-flatten) and pick the delimiter that matches your downstream consumer.

## Related Tools

- [JSON to CSV](https://pdfflare.com/tools/json/json-to-csv) — flatten first, then export to Excel-friendly CSV
- [JSON Diff](https://pdfflare.com/tools/json/json-diff) — diff flattened forms for clear structural diffs
- [JSON Formatter](https://pdfflare.com/tools/json/json-formatter) — format flat or nested output for human review
- [JSON Path](https://pdfflare.com/tools/json/json-path) — query nested data without flattening when paths suffice

---

## Frequently asked questions

**Q: What does it mean to flatten nested JSON to dot notation?**

A: Flattening converts nested objects and arrays into a single-level object whose keys describe the path to each leaf value. So {"user": {"address": {"city": "NYC"}}} becomes {"user.address.city": "NYC"}. The structure becomes part of the key. Unflattening rebuilds the nested shape.

**Q: Can I use a delimiter other than dot when flattening?**

A: Yes. PDFFlare supports four delimiter modes: dot (the default, used by most form libraries and i18n tools), underscore (for env-var-style keys like A_B_C=value), slash (for path-style keys, used by Consul KV), or Custom (type any string). The same delimiter is used for both flatten and unflatten.

**Q: What happens if a key contains the delimiter character?**

A: Keys containing the active delimiter get wrapped in ["..."] in flat form to avoid ambiguity. So {"a.b": 1} flattened with the dot delimiter becomes {'["a.b"]': 1}, and unflatten restores it correctly. This keeps the round trip safe even when keys contain delimiters.

**Q: Does flatten preserve null values and empty arrays?**

A: Yes. Null leaves become null entries at their path. Empty objects ({}) and empty arrays ([]) are preserved as a single entry with that path so unflatten can reconstruct them exactly. This makes the round trip lossless for the typical case.

**Q: Why would I flatten JSON for an environment variable config?**

A: 12-factor apps consume config as flat env vars (e.g. DATABASE_HOST=localhost). If your canonical config is nested JSON, flatten with underscore delimiter, uppercase the keys, and inject as env vars. At startup, your app reads the env, unflattens back to nested JSON, and consumes it. You get readable nested config in version control plus 12-factor-compliant env vars in production.

---

## About PDFFlare

PDFFlare is a free collection of online tools for working with PDFs, images, text, JSON, and developer utilities. All tools run client-side in your browser — no signup, no upload to our servers, no rate limits.

For the full site index, see https://pdfflare.com/llms.txt.
For the complete content dump in one file, see https://pdfflare.com/llms-full.txt.