# JSON structure analyzer

Analyze a JSON document's structure: max nesting depth, node counts, key frequency, per-path types, and array stats — in your browser. Free, private, no upload.

## Run it

- **CLI:** `gizza tool json-structure-analyzer '{ "users": [ { "id": 1, "name": "Ada" }, { "id": 2, "name": "Bo" } ] }'`
- **Web:** https://gizza.ai/tools/json-structure-analyzer/
- **Agents:** machine-readable descriptor (parameters JSON Schema) at https://gizza.ai/tools/json-structure-analyzer/tool.json

## Inputs

- `json` — JSON _(field)_
- `format` — Output format _(field)_
- `top_keys` — Max keys in frequency list (0 = all) _(field)_
- `top_paths` — Max paths in type distribution (0 = all) _(field)_

## Output

- Structure report (text)

## Query parameters

Open the tool pre-filled and auto-run via URL:

- `json` — JSON
- `format` — Output format
- `top_keys` — Max keys in frequency list (0 = all)
- `top_paths` — Max paths in type distribution (0 = all)

Example: `https://gizza.ai/tools/json-structure-analyzer/?json=%7B%20%22users%22%3A%20%5B%20%7B%20%22id%22%3A%201%2C%20%22name%22%3A%20%22Ada%22%20%7D%2C%20%7B%20%22id%22%3A%202%2C%20%22name%22%3A%20%22Bo%22%20%7D%20%5D%20%7D&format=json&top_keys=30&top_paths=50`

---

## About this tool

**JSON structure analyzer** parses a JSON document and reports its *shape* — without
transforming or reformatting the data. Paste any JSON value (object, array, or scalar)
and you get:

- **Max nesting depth** — the deepest level of objects/arrays.
- **Node counts** by type: objects, arrays, strings, numbers, booleans, and nulls,
  plus total values, total keys, unique keys, and empty values.
- **Key frequency** — how often each key name occurs across the whole document
  (recurring names counted each time), ranked most-common first.
- **Per-path type distribution** — each path (with array indices collapsed to `[]` so
  every element of an array shares one path) and the JSON types seen there. This makes
  mixed-type fields obvious.
- **Array stats** — count, min / max / average length, and total elements.
- **Byte size** — raw vs. minified, plus the compression potential of stripping
  whitespace.
- **Quality warnings** — deep nesting (more than 5 levels), recurring keys, and empty
  values.

### Worked example

For `{"users":[{"id":1,"name":"Ada"},{"id":2,"name":"Bo"}]}` the report shows root type
**object**, max depth **3** (`$` → `$.users` → `$.users[]` → `$.users[].name`), key
frequency `id: 2, name: 2, users: 1`, and the path `$.users[]` with **2** objects. The
`name` field lands at `$.users[].name` as a **string** seen twice.

### Options

- **Output format** — *JSON report* (structured, easy to diff or feed to another tool)
  or *Plain text* (a human-readable summary of the same data).
- **Max keys** and **max paths** — cap the key-frequency and per-path lists (set `0` to
  list everything). A truncation flag tells you when a list was cut.

### Privacy

Everything runs **in your browser** via WebAssembly — your JSON is never uploaded. The
tool is also available from the [gizza CLI](/) and in chat, which return the report as
structured JSON.

## FAQ

<details>
<summary>How is nesting depth counted?</summary>

The root value is depth **0**, and each step into an object or array adds one. So
`{"a":1}` is depth **1**, `{"a":{"b":1}}` is depth **2**, and a scalar like `42` on its
own is depth **0**. Depth over **5** levels raises a "deep nesting" warning, since deeply
nested data is harder to read and query.

</details>

<details>
<summary>What does the per-path type distribution show, and why collapse array indices?</summary>

Each path is written with `$` for the root, `.key` to descend an object, and `[]` to
descend an array — so all elements of an array share **one** path (`$.users[]` rather
than `$.users[0]`, `$.users[1]`, …). That collapse is what makes a mixed-type field
jump out: if `$.items[].price` reports `["number", "string"]`, some prices are strings.
Paths are ranked by how many nodes were seen at each one.

</details>

<details>
<summary>What counts as an "empty value"?</summary>

An empty value is a `null`, an empty string (`""`), or an empty object/array (`{}` /
`[]`). They're counted together in the `empty_values` total and surface a warning, which
is handy for spotting placeholder fields or optional data that never got filled in.

</details>

<details>
<summary>Can it handle very large JSON, and what about invalid JSON?</summary>

Large documents are fine — parsing and the single walk are linear, and the whole thing
runs locally so there's no upload size limit beyond your browser's memory. If the input
isn't valid JSON, you get a clear parse error (with the position) instead of a partial
report, so you know exactly what to fix.

</details>

## Related tools

- [Avro to JSON Converter](https://gizza.ai/tools/avro-to-json/): Decode Apache Avro Object Container Files (.avro / OCF) to JSON, NDJSON, or the embedded schema — no .avsc needed, free and private in your browser.
- [Bencode decoder](https://gizza.ai/tools/bencode-decoder/): Decode bencode (the BitTorrent / .torrent serialization format) into readable JSON, and re-encode JSON back into canonical bencode — in your browser. Nothing is uploaded.
- [CAMT.053 Statement Parser](https://gizza.ai/tools/camt053-parse/): Parse a camt.053 (or camt.052/054) ISO 20022 bank statement XML into JSON or CSV in your browser: balances, dates, counterparties, references. No upload.
- [Find CSV rows with no matching key](https://gizza.ai/tools/csv-anti-join/): Return rows in CSV A whose key has no match in CSV B, or the reverse, with composite keys, alternate delimiters, and browser-local processing.
- [CSV Cell Diff](https://gizza.ai/tools/csv-cell-diff/): Compare two CSVs column-by-column and highlight every individual cell that changed, plus added and removed rows and columns.
