JSON Path Tester
Test JSONPath expressions against your JSON live as you type β filters, slices, unions and recursive descent all supported, with the Path, JSON Pointer and Value shown for every match. Runs entirely in your browser.
| # | Path | Type | Value |
|---|---|---|---|
| 1 | $['store']['book'][0]['author'] | string | "Nigel Rees" |
| 2 | $['store']['book'][1]['author'] | string | "Evelyn Waugh" |
| 3 | $['store']['book'][2]['author'] | string | "Herman Melville" |
| 4 | $['store']['book'][3]['author'] | string | "J. R. R. Tolkien" |
Tips for Writing JSONPath That Actually Matches
- Start broad, then narrow. Query $.store.* first to confirm the shape of the data before writing a specific filter β a wrong assumption about nesting is the single most common reason a query returns nothing.
- Quote string values inside filters. [?(@.category=="fiction")] works; [?(@.category==fiction)] doesn't, since the unquoted word is treated as an identifier, not a string literal.
- Reach for recursive descent (..) sparingly on large documents. It's the most powerful operator here and also the slowest, since it has to visit every node below the starting point.
- Turn on Ignore Evaluation Errors before assuming a filter is broken if your array has inconsistent shapes β one item missing a field a filter checks is enough to abort the whole query otherwise.
Features
Reading a JSONPath Expression Left to Right
Every JSONPath expression starts at $, the root of the document, and reads like a set of directions from there. $.store.book[0].title steps into store, then book, takes the first element of that array, then reads its title β each segment narrowing the previous one. Swap the dot for two dots and the meaning changes from "go exactly here" to "search everywhere below this point": $..title finds a title field no matter how deeply it's buried, without you having to know or write out the exact path to it. A wildcard, *, means "every child, whatever its name" β $.store.* returns both the book array and the bicycle object in one query, since both are direct children of store.
Bracket notation exists for the cases dot notation can't express cleanly: array indexes ([0]), several indexes at once as a union ([0,1]), a range as a slice ([0:2]), or a property name that isn't a valid identifier, like one containing a space or a hyphen (["my-field"]). All of these are interchangeable with dot notation where dot notation would work at all β bracket syntax is simply the more general form.
Filters Are Where Real Debugging Happens
Most of the JSONPath queries people actually reach for in day-to-day debugging aren't navigation β they're filtering. A filter expression sits inside [?( )] and is evaluated once per candidate node, with @ standing in for whatever node is currently being tested. $..book[?(@.price<10)] keeps only the books cheaper than 10; $..book[?(@.isbn)] keeps only the ones that have an isbn field at all, regardless of its value β an existence check rather than a comparison. Combine conditions with && and || the same way you would in ordinary JavaScript, since that's effectively what's being evaluated under the hood in a sandboxed, CSP-safe way.
Three Ways to Look at the Same Match
A single matched node can be described three different ways, and each one is the right answer to a different question. The Value is what you actually wanted β the string, number, or object the query found. The Path is the exact JSONPath expression that would, on its own, target that one specific node β handy for taking a broad query's result and turning it into a precise one. The Pointer is the same location expressed as an RFC 6901 JSON Pointer, like /store/book/0/title, the format expected by tools like JSON Patch or an OpenAPI $ref. Rather than picking one and re-running the query when you actually needed a different one, this tester evaluates once and shows all three side by side, along with the value's type β string, number, boolean, null, object or array β so a null and an empty string are never mistaken for each other at a glance.
A Debugging Session, Start to Finish
The usual trigger is a backend response that doesn't look right β a field missing, a value in the wrong shape, something a test assertion is about to fail on. Instead of adding a console.log and re-running the request, paste the raw JSON here and query directly against it. A recursive filter like $..[?(@.level=="error")] pulls every matching record out of a deeply nested log export in one shot, no script required just to look. If the field itself turns out to need pattern-matching rather than structural lookup β checking whether a value is a valid email or ID format β that's a job for the Regex Tester, not this tool; JSONPath finds the field, regex validates what's inside it.
The same approach works before a config file ever reaches production, not just after something breaks. Convert a YAML manifest with YAML to JSON, or an XML payload with XML to JSON, then query the result to confirm every key a deployment script expects is actually present. Because evaluation runs entirely in the browser tab, none of it β API responses, log exports, or configs carrying internal hostnames β ever leaves your machine to get an answer.
When a Query Returns Nothing
An empty result almost always traces back to one of a small number of causes. Property names are case-sensitive, so Title and title are different fields entirely. A filter comparison against a string needs quotes around that string, or it's parsed as an identifier instead. A single dot where the data is actually nested one level deeper simply won't find anything, and unlike a strict parser, this tool leniently accepts some malformed bracket syntax rather than erroring β which can produce a confusing unexpected match instead of a clear failure. If you're debugging a JSON Formatter-clean document and still getting nothing back, query the parent with a wildcard first and rebuild the path one segment at a time from there.
Not Every JSONPath Implementation Agrees
JSONPath spent over fifteen years as an informal convention before RFC 9535 gave it a formal core in 2024, and in that time several implementations β Goessner's original, Jayway's Java library, Python's jsonpath-ng, and the JSONPath-Plus engine this tool runs β each extended the syntax slightly differently, particularly around filter expressions and script evaluation. A query written for one may need small adjustments in another. That's not a flaw specific to any single tool; it's the actual state of JSONPath as an ecosystem, and worth knowing before assuming a query that works here will behave identically inside, say, a Python script using a different library β test the exact expression against the exact engine your production code will actually run.