A worked example: learning a format from its tree

The tree view is at its best on a format you have not worked with before. Take GeoJSON, the standard format (RFC 7946) that mapping libraries such as Leaflet and Mapbox load. Here is a small file with two features - a point of interest and a walking route:

{
  "type": "FeatureCollection",
  "bbox": [-0.1419, 51.5007, -0.1246, 51.5081],
  "features": [
    {
      "type": "Feature",
      "id": "poi-17",
      "geometry": { "type": "Point", "coordinates": [-0.1281, 51.5081] },
      "properties": { "name": "Trafalgar Square", "category": "landmark", "step_free": true }
    },
    {
      "type": "Feature",
      "id": "route-4",
      "geometry": {
        "type": "LineString",
        "coordinates": [[-0.1419, 51.5014], [-0.1332, 51.5031], [-0.1246, 51.5007]]
      },
      "properties": { "name": "The Mall to Westminster", "surface": "paved", "lit": true,
                      "closures": [{ "from": "2026-11-09", "reason": "ceremony" }] }
    }
  ]
}

As a tree:

type  (string)
bbox  (array)
features  (array)
  type  (string)
  id  (string)
  geometry  (object)
    type  (string)
    coordinates  (array)
  properties  (object)
    name  (string)
    category  (string)
    step_free  (boolean)
    surface  (string)
    lit  (boolean)
    closures  (array)
      from  (string)
      reason  (string)

Seventeen lines, and the whole format is visible. A real map export with ten thousand features would produce much the same tree - a few more property names, perhaps - because the tree grows with the variety of the data, not its volume.

What the tree tells you

Reading that outline top to bottom, you can learn most of GeoJSON without opening the specification:

  • There is a fixed envelope. Both the collection and each feature carry a type string. That is how GeoJSON readers tell the levels apart.
  • geometry and properties are siblings. The shape of a feature lives in one object and everything else you know about it lives in the other - so your own data goes in properties, never alongside geometry.
  • properties is free-form. It mixes category and step_free from the point with surface, lit, and closures from the route. The tree merges every feature's properties into one branch, which is exactly what you want when you are asking "what attributes does this dataset use?"
  • Nesting goes four levels deep at features[].properties.closures[].from. That is the depth your accessors, or your column mapping, will need to reach.

What the tree hides

A structural view throws information away on purpose, and it is worth knowing what went.

  • Which element has which field. surface is in the tree, but only the route has it. The tree says a field can appear, not that it always does. The dot-notation flattener with literal indices shows the per-element truth.
  • What is inside a plain array. coordinates (array) is a leaf, because the tree only draws branches for object keys. It cannot show you that a Point's coordinates are a pair of numbers while a LineString's are a list of pairs.

That second gap is the interesting one, and another format closes it. Switch the output to TypeScript interface and coordinates comes back as:

coordinates: (number | number[])[];

That is the type you get by pooling both features' coordinates - a mix of bare numbers and number arrays - and it is the tool's way of telling you that the same key holds different shapes depending on geometry.type. In GeoJSON that is by design; in an API you are integrating with, it is usually the first bug you would otherwise hit. The practical habit: use the tree to learn the shape, then switch formats to question the parts it flattened.

One more thing the tree cannot tell you, because it is a convention rather than structure: GeoJSON writes positions as [longitude, latitude], the opposite order to how most people say coordinates aloud. The sample's -0.1281 is the longitude of central London.

Why array indices are always collapsed

The two features above produce one features branch, not two. For an array of five thousand features, drawing one branch per element would print the same seven lines five thousand times and bury the shape. So the tree always merges repeated array positions, and there is no option to turn that off - if you want per-element output, the other formats respect the Collapse array indices checkbox.

Tree view vs a JSON formatter

JSON formatterTree view
Keeps valuesYes, all of themNo, structure only
Output lengthGrows with the dataGrows with the schema
Repeated array elementsPrinted in fullMerged into one branch
Shows typesImplicitly, by syntaxExplicitly, on every line
Best forReading one specific recordUnderstanding an unfamiliar payload

They work well together: use the tree to find where the field you care about lives, then look it up in the formatted document. The same tool does both - switch the format to Formatted JSON to get the document back with its values.

Good places to use it

  • Pull request descriptions. Paste the tree of a new response so reviewers see its shape without scrolling through sample data.
  • Structural drift. Save the tree of an API response today and diff it against next month's. Changed values do not show up, so every changed line is a schema change.
  • Unfamiliar exports. Analytics dumps, config files, and data-portal downloads often come with thin documentation. The tree is a faster first read than any of them.

Reading the type labels

Each line ends with the JSON type of that key's value: object, array, string, number, boolean, or null. All numbers are number, because JSON does not distinguish integers from floats. And a key whose value is null in your sample is labelled null, even if the API usually sends a string there - the label describes the document you pasted, not the contract behind it.

Other output formats

Further reading

Written and maintained by Ashish Singh · Last updated · Changelog · Found a problem with this page? Tell me.