JSONPath Tester

Query pasted JSON with selectors and simple comparison filters, then inspect each matching value and its path. Unsupported syntax is rejected; the tool does not execute JavaScript expressions.

Runs locally in your browser
JSON document
Query expression

Supports names, bracket notation, indexes, wildcards, unions, slices, descendant selectors, and simple comparison filters.

Core query parsing is performed locally. Unsupported expression forms return a clear error rather than falling back to eval().

Matches
Run a JSONPath expression to inspect matching values.

How to run a JSONPath query

Paste a JSON document, type a JSONPath expression and read every match as a normalized path with its value. The query runs on the text in this tab: nothing is uploaded and no request leaves the page.

The parser was written for this tool and never falls back to eval(). Syntax it does not implement stops with a named error: combined filters with &&, || or ! are refused, and so is comparing a filter against the document root.

  1. Paste the document into JSON document, or press Load example to start from the bookstore sample.
  2. Type the expression into Query expression. The four examples above the buttons ($.store.book[*].author, $..price, $.store.book[?(@.price < 10)], $.store.book[0:2]) fill the field and run straight away when a document is already loaded.
  3. Press Run query. The Matches card lists one entry per node: the normalized path on the left, the JSON value on the right.
  4. Press Copy result JSON to take the matched values as a single JSON array, or Clear to empty the document and reset the results.

What this JSONPath tester supports

Selectors that work

Names, quoted names and indexes: $.store.book, $["store"]["book"], $['store']['bicycle'], [0], [-1] for the last element, and unions such as [0,1] or ['a','b']. A name outside brackets starts with a letter, underscore or $ and continues with letters, digits, underscore, $ or hyphen; a key that contains a dot or a space has to use the bracket form.

Wildcards, slices and descendants: $.store.*, $..price, [0:2], [::2], [::-1]. Slices follow the same bounds as Python: a negative boundary counts from the end and a negative step walks backwards.

Filters: one comparison per bracket

A filter evaluates a single comparison and accepts ==, !=, <, <=, > and >= against a number, a quoted string, true, false or null: [?(@.price < 10)] or [?(@.title == "Moby Dick")]. A filter without an operator keeps the nodes where the property exists and is truthy: [?(@.isbn)].

What the parser cannot evaluate is refused instead of guessed: [?(@.price > 1 && @.price < 10)] answers that combined filters are not supported, [?(@.price > $.expensive)] that a filter cannot compare against the root, and a regular expression such as =~ /a/ that the filter expression is unsupported.

Paths, copies and large inputs

Every match reports its path in one normalized form, $["store"]["book"][0]["author"], whatever notation the query used, and the same node is never listed twice. Copy result JSON returns the matched values as one JSON array, ready for a fixture or a diff.

The Matches card renders the first 200 results and then states how many were left out; the copy button still carries the complete array. A 50,000-node document answers a wildcard query in under a second, and deeply nested documents are walked without a stack overflow.

Recent tools: