JSONPath Query
Last updated: 2 October 2026
Run a JSONPath expression against a JSON document and see every match, each with the path it was found at. The query runs in your browser; the document is never sent anywhere.
What the query language does
JSONPath is to JSON what a folder path is to a filesystem: a compact way to say which values you want. $ is the document root, .name walks into a property, and […] selects inside an array.
- Children:
$.store.bicycle.coloror$['store']['bicycle']['color']when a name needs quoting. - Wildcards:
$.store.book[*].titletakes the title of every book;$.store.*takes every value of the store object. - Recursive descent:
$..pricefinds apriceat any depth. Powerful, and easy to over-match — see below. - Indexes and slices:
[0],[-1]for the last item,[0:2]for the first two,[0:5:2]to step. - Unions:
[0,2]and['book','bicycle']select several at once. - Filters:
[?(@.price < 10)]keeps the items whose price is under ten, with== != < <= > >=and combinations using&&and||.
Filters test existence, not truthiness
A filter with a bare path asks whether the property is there. So [?(@.inStock)] matches an item whose inStock is false, because the property exists — the RFC 9535 reading. When you mean the value, say so: [?(@.inStock == true)]. This is the single most common surprise in JSONPath, and it is a property of the language rather than of this tool.
What it deliberately does not do
Filter functions such as length(), match() and search() are not implemented, nor are regular expressions, script expressions in parentheses, or the parent/sibling extensions that some libraries add. A query using them is rejected with a message rather than quietly returning the wrong result — the page states what it supports so a pass here means what it says.
Frequently Asked Questions
Which JSONPath syntax is supported?
Root $, child access with .name or ['name'], the wildcards .* and [*], recursive descent with ..name and ..*, array indexes including negative ones, slices [start:end:step], unions such as [0,1] and ['a','b'], and filters [?(@.price < 10)] with the operators == != < <= > >= combined using && and ||.
What is not supported?
Filter functions such as length(), match() and search(), regular expressions, script expressions in parentheses, and the JSONPath extensions some libraries add, such as parent and sibling references. A query that uses them is rejected rather than silently returning the wrong thing.
Why does ?(@.inStock) match items where inStock is false?
Because a bare path in a filter is an existence test, not a truthiness test: it asks whether the property is there, and a property set to false is still there. For truthiness write ?(@.inStock == true) explicitly. That is the RFC 9535 reading of a filter.
Does a match tell me where it came from?
Yes. Each result is listed with the path it was found at, in the same dotted and bracketed notation used to write queries, so the same path can be pasted back into a query or into another JSON tool.
Is my document uploaded?
No. The document is parsed with JSON.parse in your browser and the query runs in memory. Nothing is uploaded, and the page keeps working with the network disconnected.
Why did $..price return more than I expected?
Recursive descent visits every level of the document, so ..price finds a price property wherever it appears — inside arrays, nested objects and unrelated branches alike. To narrow it, anchor the query with more of the path, such as $.store.book[*].price.
Want to check a document against a schema instead? JSON Schema does that. Spotted a bug? Get in touch.