# JSONPath Tester

> Test a JSONPath expression against your JSON and see every matching node with its path. Runs in your browser, with filters supported.

Canonical: https://host-tools.com/tools/jsonpath-tester/

---

## JSONPath, in one sentence

JSONPath is a **selector**: you give it a path and it returns the nodes that path points to. It does
not transform, compute or reshape anything. If you want to group, sum or rewrite data, that is a
different tool.

## JSONPath is not jq

This site has both, and they are deliberately different:

| | JSONPath Tester | JSON Query |
| --- | --- | --- |
| Purpose | select nodes | transform data |
| Syntax | `$.users[*].name` | `.[] \| select(.active)` |
| Output | the matching nodes and their paths | a new JSON document |
| Good for | "where is this field?" | "give me a different shape" |

If your expression contains arithmetic, `map`, `group_by` or builds a new object, you want
[JSON Query](/tools/json-query/). If it is a path with wildcards or a filter, this is the one.

## The syntax worth knowing

```
$.store.book[0].title        first element, by index
$.store.book[*].title        every element
$..price                     every price, at any depth
$.users[?(@.active)]         elements where active is true
$.users[?(@.age > 18)].name  comparison inside a filter
$['weird key']               keys that are not valid identifiers
```

Two details that surprise people: `$..x` (recursive descent) is greedy and can return a lot, and
filter expressions run against each element, so `@` is the current node.

## How filters stay safe

Filters like `?(@.active)` are expressions, and a naive implementation evaluates them with
`Function`, which turns a JSON field into a place to run code. This tool uses a restricted
evaluator: the expression can read the data, and nothing else. That is why an expression that tries
to call arbitrary methods fails instead of executing.

## When nothing matches

Zero results is a valid answer, not an error, and it is usually one of three things: the path has a
wrong case, the data is an object where you expected an array (or the reverse), or the filter uses a
field that does not exist on that element. The tester keeps syntax errors and empty results
separate, because they need different fixes.

Format the JSON first with [JSON Formatter](/tools/json-formatter/) if you are not sure it is even
valid.
