Skip to main content
DevBench
All articles
jsonreferencejavascript

JSONPath Cheat Sheet: Query Any JSON Document

June 27, 20266 min read

JSONPath is a query language for JSON, analogous to XPath for XML. Given a deeply nested JSON document, a JSONPath expression lets you extract one value, a list of values, or everything that matches a pattern — without writing loops. It is supported natively in PostgreSQL (jsonb_path_query), AWS CloudFormation, Kubernetes admission webhooks, and most API testing tools.

Root and current node

SymbolMeaning
$Root of the document
@Current node (used inside filter expressions)

Every JSONPath expression starts with $.

Navigation operators

OperatorMeaningExample
.keyChild key (dot notation)$.user.name
["key"]Child key (bracket notation — use for keys with spaces or special chars)$["first name"]
[n]Array element at index n (0-based)$.items[0]
[*]All array elements (wildcard)$.items[*].id
.*All children of current node$.user.*
..Recursive descent — searches all depths$..name

Array slicing

JSONPath supports Python-style slice notation [start:end:step]:

ExpressionResult
$.a[0:3]Elements at index 0, 1, 2
$.a[-1]Last element
$.a[::2]Every second element (0, 2, 4 …)
$.a[1,3]Elements at index 1 and 3 (union)

Filter expressions

Filter expressions use ?(…) syntax to select elements that satisfy a condition. Inside the filter, @ refers to the current array element:

ExpressionSelects
$.items[?(@.price < 10)]Items where price is less than 10
$.users[?(@.active == true)]Active users
$..book[?(@.isbn)]Any book with an isbn field
$.orders[?(@.total >= 100 && @.status == "shipped")]Shipped orders over $100

Practical examples

Given this document:

{
  "store": {
    "books": [
      { "title": "Clean Code",    "price": 29.99, "inStock": true  },
      { "title": "Refactoring",   "price": 34.99, "inStock": false },
      { "title": "The Pragmatic Programmer", "price": 39.99, "inStock": true }
    ]
  }
}
ExpressionResult
$.store.books[*].titleAll three titles
$.store.books[-1].title"The Pragmatic Programmer"
$.store.books[?(@.inStock)].title"Clean Code", "The Pragmatic Programmer"
$.store.books[?(@.price < 35)].title"Clean Code", "Refactoring"
$..priceAll three prices (recursive)

JSONPath in JavaScript

No native browser or Node.js API supports JSONPath — you need a library. The most widely used is jsonpath-plus:

import { JSONPath } from "jsonpath-plus";

const result = JSONPath({
  path: "$.store.books[?(@.price < 35)].title",
  json: document,
});
// ["Clean Code", "Refactoring"]

JSONPath in PostgreSQL

PostgreSQL 12+ supports the SQL/JSON standard path language (similar to JSONPath) via jsonb_path_query:

SELECT jsonb_path_query(data, '$.store.books[*] ? (@.price < 35).title')
FROM products;

Gotchas

  • No universal standard — RFC 9535 (2024) finally standardised JSONPath, but many tools pre-date it and differ in filter syntax and recursion behaviour. Test your expressions against your specific library.
  • Recursive descent is slow on large documents$..key traverses the entire tree. Use specific paths in performance-sensitive code.
  • Missing nodes return an empty array, not null — account for this in your error handling.

Try it yourself

Use the free browser-based JSON Formatter & Validator on DevBench — no signup, runs entirely in your browser.

Open JSON Formatter & Validator