A fast, friendly and portable JSON query language for the command line.
query-json lets you slice, filter, and transform JSON data with a concise, expressive syntax. It started as a jq-compatible implementation, but evolved into something better: faster execution, better error messages, and a modernized language design.
Native binary compiled with OCaml. Consistently 2-4x faster than jq across file sizes and operations.
| File Size | Speed vs jq |
|---|---|
| < 10KB | 2.4-3x faster |
| 100-500KB | 2-4.5x faster |
| > 500KB | 1.6-3.3x faster |
Designed to be learnable without leaving your terminal:
- Interactive REPL with context-aware autocomplete—type
.to see keys,|to see functions - Helpful error messages that tell you why something failed and how to fix it
- Built-in function reference:
query-json --functionslists all functions by category
$ query-json ".naem" <<< '{"name": "Alice", "age": 30}'
error[key_not_found]: key `naem` not found
--> .naem
^^^^
in: {"name": "Alice", "age": 30}
available keys: name, age
hint: use `.naem?` for optional accessCompare to jq
$ jq ".naem" <<< '{"name": "Alice", "age": 30}'
nullWritten in OCaml, it compiles to both native code and JavaScript. Use the same query language:
- As a CLI tool on macOS, Linux, and Windows
- In the browser via our online playground
- As a Node.js library:
npm install @davesnx/query-json
We love jq's core ideas, but most of their design is arcane and forced the be backwards compatible. We looked into it with fresh eyes and came up with some improvements:
- Consistent style: All functions use
snake_case - Stricter nulls: Errors on null access instead of silently propagating (use
.foo?for optional) - Optional access everywhere:
first?,last?,keys?and evenfirst?(expr)work as expected - Readable names:
to_uppercaseinstead ofascii_upcase,starts_withinstead ofstartswith - Saner defaults:
group_byreturns an object (not nested arrays),keys/uniquepreserve insertion order - Extra functions:
filter,flat_map,find,pluck,compact,partitionand more fnfor user defined functions:fnkeyword instead ofdef
The old jq names still work but show deprecation warnings. See the full jq Compatibility Guide for details.
Check the content of scripts/install.sh before running anything in your local. Friends don't let friends curl | bash.
curl -sfL https://query-json.page.dev/install.sh | bashnpm install --global @davesnx/query-jsonPre-built binaries for macOS, Linux, and Windows are available on the releases page.
query-json '.store.books[0].title' bookstore.jsoncurl -s https://api.github.com/users/ocaml | query-json '{name: .name, description: .bio, img: .avatar_url}'query-json '.users | length' '{"users": [1, 2, 3]}'# Get all keys from an object
query-json 'keys' config.json
# Filter array elements
query-json '.items | map(select(.price > 100))' products.json
# Transform data
query-json '.users | map({name, email})' users.json
# Group and count
query-json 'group_by(.category) | map_values(length)' items.json
# String operations
query-json '.title | to_lowercase | split(" ") | first' article.json- Try it online - Interactive playground
- Function Reference - Complete list of built-in functions
- jq Compatibility Guide - Migration guide for jq users
query-json [OPTIONS] <QUERY> [FILE]
Arguments:
<QUERY> The query to run
[FILE] JSON file to query (reads from stdin if omitted)
Options:
-r, --raw-output Output strings without quotes
--no-color Disable colored output
--repl Start interactive REPL mode
-v, --verbose Show verbose output including deprecation warnings
--debug Print lexer tokens and AST
--version Print version
--help Print help
Contributions are welcome! See the development setup below to get started.
Requirements: opam
git clone https://github.com/davesnx/query-json
cd query-json
make init # Create opam switch and install dependencies
make dev-core # Build query-json
make test # Run tests# Terminal 1: Build and watch
make dev
# Terminal 2: Start web server
make web-dev- Twitter/X: @davesnx
- Discord: discord.gg/reasonml
- Email: dsnxmoreno at gmail dot com
MIT
