JSONPath or JSON Pointer
Bottom line: JSON Pointer is a unique address you can store as a key; JSONPath is a query language. Using the wrong one breaks config updates or reinvents a broken JSONPath.

Bottom line: use JSON Pointer when you need to read, write or store the address of one node (for example /server/cors/0), and JSONPath when you need to select a set of nodes by condition; any persisted path should be a Pointer, never an expression.
Ask whether you need one node or a set of them.
In one table
| JSON Pointer | JSONPath | |
|---|---|---|
| Nature | Unique address | Query expression |
| Syntax | /a/b/0 |
$.a.b[0], $..price |
| Result | Exactly one node, or none | Zero or more nodes |
| Storable as a key | Yes, the string is the identity | No, may match many |
| Standard | RFC 6901 | RFC 9535 (finalised 2024) |
JSON Pointer
/server/host -> "127.0.0.1"
/server/cors/0 -> "https://a.com"
/ -> the whole document
Keys containing / or ~ are escaped: ~0 for ~, ~1 for /. The value is determinism: the address is a string, so it fits in a database column, a log line, or a config key. JSON Patch (RFC 6902) addresses every operation this way.
JSONPath
$.store.book[*].author
$..price
$.store.book[?(@.price < 10)]
Closer to SQL WHERE. The same expression returns zero, one or a hundred nodes depending on the data.
Two failure modes
Using JSONPath as a config key. Store $.server.port and one day the structure becomes an array; the expression now matches several ports and the update logic has no way to choose.
Using Pointer for selection. "Find every node whose price is under 10" is impossible with a pointer. Writing the loop yourself means building a partial JSONPath.
How real systems split the work
- Config reads, field updates, patches: Pointer, fixed and auditable
- Data exploration, bulk extraction, reporting: JSONPath, expressiveness first
- Anything persisted: Pointer only, never an expression
FAQ
How should I choose between JSON Pointer and JSONPath?
Ask whether you need one node or a set. Use JSON Pointer to read or write one specific node and to store that address as a key, because the pointer is unique, for example /server/cors/0. Use JSONPath to select nodes by condition, for example $.store.book[?(@.price < 10)].
Why can't a JSONPath expression be used as a config key?
Because the expression may match several nodes. Store $.server.port and one day the structure becomes an array; the expression then matches multiple ports and the update logic cannot decide which one to change. Anything persisted or audited needs a Pointer.
Can JSON Pointer filter nodes by condition?
No. A pointer only walks a fixed path and has no way to know which nodes exist, so selecting every node whose price is under 10 is impossible. Writing that loop yourself means building a partial JSONPath.