JSONata Debugger

Last updated on 15 Aug 2026

Overview

The JSONata debugger allows you to see the evaluated result of individual steps in an expression.

It works by converting the expression into an AST (Abstract Syntax Tree), evaluating each node of the tree, and visualising the results in a tree-like structure.

The debugger is part of the JSONata Playground but is available to paid users only.

Usage

Given the JSONata expression

services[
  locationDetail.operator = "Northern" and
  $number(locationDetail.platform) = 12
]

and JSON input

{
  "location": {
    "id": 53790154,
    "name": "Leeds",
    "crs": "LDS",
    "tiploc": "LEEDS"
  },
  "services": [
    {
      "locationDetail": {
        "description": "Leeds",
        "gbttBookedDeparture": "14:15",
        "realtimeDeparture": "14:17",
        "platform": "12",
        "operator": "Northern",
        "destination": [
          {
            "id": 53950109,
            "tiploc": "YORK",
            "description": "York"
          }
        ]
      },
      "trainIdentity": "1Y42"
    },
    {
      "locationDetail": {
        "description": "Leeds",
        "gbttBookedDeparture": "14:30",
        "realtimeDeparture": "14:30",
        "platform": "8",
        "operator": "LNER",
        "destination": [
          {
            "id": 51530012,
            "tiploc": "KGX",
            "description": "London Kings Cross"
          }
        ]
      },
      "trainIdentity": "1D22"
    }
  ]
}

the debugger will output the following tree structure

Debug Output
Debug Step Result

Each node in the tree represents a step in the expression evaluation. Clicking on a node displays its result.

The first node is the whole expression which contains 3 child nodes

  1. services
    
  2. locationDetail.operator = "Northern" and $number(locationDetail.platform) = 12
    
  3. locationDetail.operator = "Northern" and $number(locationDetail.platform) = 12
    

In this example, the last two child nodes are identical because the filter is applied two times since the services node evaluates to an array of two objects.

[
  {
    "locationDetail": {
      "description": "Leeds",
      "gbttBookedDeparture": "14:15",
      "realtimeDeparture": "14:17",
      "platform": "12",
      "operator": "Northern",
      "destination": [
        {
          "id": 53950109,
          "tiploc": "YORK",
          "description": "York"
        }
      ]
    },
    "trainIdentity": "1Y42"
  },
  {
    "locationDetail": {
      "description": "Leeds",
      "gbttBookedDeparture": "14:30",
      "realtimeDeparture": "14:30",
      "platform": "8",
      "operator": "LNER",
      "destination": [
        {
          "id": 51530012,
          "tiploc": "KGX",
          "description": "London Kings Cross"
        }
      ]
    },
    "trainIdentity": "1D22"
  }
]

The filter locationDetail.operator = "Northern" and $number(locationDetail.platform) = 12 is applied to each object in the array.

The first iteration returns true and the second returns false. Navigating deeper into the tree reveals why.

The first filter node has two child nodes

  1. locationDetail.operator = "Northern"
    
  2. $number(locationDetail.platform) = 12
    

When applied to the first object in the array, locationDetail.operator resolves to "Northern" and locationDetail.platform to "12". The first filter node resolves to true.

The second filter node has only one child node

  1. locationDetail.operator = "Northern"
    

When applied to the second object in the array, locationDetail.operator resolves to "LNER" which forces the second filter to resolve to false and return early.

Eventually, the whole expression evaluates to a single train service.

{
  "locationDetail": {
    "description": "Leeds",
    "gbttBookedDeparture": "14:15",
    "realtimeDeparture": "14:17",
    "platform": "12",
    "operator": "Northern",
    "destination": [
      {
        "id": 53950109,
        "tiploc": "YORK",
        "description": "York"
      }
    ]
  },
  "trainIdentity": "1Y42"
}