Query JSON with JSONPath or JSONata expressions
Navigating large JSON payloads by eye is slow and error-prone. This tool gives you two battle-tested query languages to extract exactly what you need. JSONPath uses a familiar dollar-dot syntax ($.store.books[*].title) borrowed from XPath for XML. JSONata is a more expressive functional language with built-in operators for filtering, mapping, sorting, and aggregating. Paste your JSON, write an expression, and the result evaluates live. Both engines run entirely in your browser — JSONPath via the jsonpath-plus library, JSONata via the official jsonata npm package.
How to query
- 1Paste JSON data into the left editor panel.
- 2Select a query language: JSONPath or JSONata.
- 3Type your expression in the query bar (a placeholder shows syntax for the selected language).
- 4Click Run or press Enter. The matching result renders on the right as formatted JSON.
- 5If the expression is invalid, a specific error message appears above the output.
Under the hood
- JSONPath (`jsonpath-plus`) — Implements the Goessner JSONPath specification with extensions: recursive descent (
..), array slicing ([0:3]), filter expressions ([?(@.price<10)]), and script expressions. - JSONata — A Turing-complete query and transformation language. Supports path navigation, wildcards, array mapping, conditional logic, string functions, aggregation (
$sum,$avg), and user-defined functions. - Live error feedback — Syntax errors in expressions are caught and displayed immediately with the engine's native error message — not a generic failure notice.
- Result formatting — Query results are always pretty-printed as JSON with 2-space indentation, regardless of the input formatting.
- Zero backend — Both query engines are bundled as npm packages and execute in the browser. No data is transmitted anywhere.
Real-world scenarios
- Extract nested fields — Pull all email addresses from a deeply nested user array with a single JSONPath expression:
$.users[*].contact.email. - Filter by condition — Use JSONata to find all products where price > 100 and category = "electronics":
products[price > 100 and category = "electronics"]. - Aggregate values — Compute the total of an array field with JSONata:
$sum(orders.total). No JavaScript required. - Reshape payloads — Use JSONata's object constructor syntax to transform a flat array into a grouped structure:
{ "byCity": orders{ city: $sum(total) } }. - Debug API responses — Test JSONPath expressions against a real API response before hardcoding them into your application code.
Query examples
// JSONPath — select all book titles:
$.store.books[*].title
// Result: ["The Great Gatsby", "To Kill a Mockingbird", "1984"]
// JSONPath — filter by price:
$.store.books[?(@.price < 9)]
// Result: [{ "title": "1984", "price": 8.99 }, ...]
// JSONata — sum all prices:
$sum(store.books.price)
// Result: 26.97
// JSONata — reshape to title:price map:
store.books.{ title: price }
// Result: { "The Great Gatsby": 9.99, ... }Questions
What is the difference between JSONPath and JSONata?
JSONPath is a path-based selector language similar to XPath — good for extracting values at known paths. JSONata is a full expression language with functions, aggregation, conditional logic, and the ability to reshape data. Use JSONPath for simple extraction, JSONata for transformation.
Which JSONPath implementation is used?
The jsonpath-plus library, which extends the original Goessner specification with sandbox-safe script expressions, filter operators, and result type options.
Can JSONata expressions modify the original data?
JSONata is purely functional — expressions produce new values without mutating the input. The original JSON in the left panel is never modified.
Why does my JSONPath return an array for a single value?
JSONPath always returns an array of matches by default. If your expression matches one item, the result is a single-element array. This is consistent with the specification.