jsongrep's examples print the path of every match, then admit that piping hides it
A path query language for JSON, YAML, TOML, and other serialization formats.
At a glance
- What is it?
- A Rust tool that queries JSON, YAML, TOML, JSONL and two binary formats with regular path expressions compiled to a finite automaton, and prints where each value came from. The comparison with a rival filter tool is honest, and the benchmark table is a link.
- Who is it for?
- This is a small, well-documented tool with one decision you have to notice before you rely on its output. The defining feature is that every match carries its path, and the comparison section spends its best example on that, since printing the path is genuinely useful when you are exploring an unfamiliar document.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 19 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The examples print paths, and the note says piping hides them
The tool's answer to a query is a path and a value, which is the thing it claims a filter pipeline does not give you. The first example pulls first names out of a Nobel Prize API response and prints three lines, each prefixed with the location the value came from. Then comes the parenthetical that every user will hit: the examples show terminal output, and when piped the path headers are hidden by default, with two flags to control it. So the visible difference between the two tools is documented and then, for readers following the examples, largely absent, because each comparison runs through a second command. The feature is real and the default is defensible for scripting. It is just worth knowing that the page's own demonstrations of it are not what you will see, which is why the two flags exist in the first place.
The benchmark section is a heading, an empty paragraph and two links
The performance section is the one place the page promises numbers and does not show them. It states the methodology first, which is better than most: four groups isolating the parse of a string into a document, the compilation of a query, the search on a pre-parsed document with a pre-compiled query, and the full pipeline; four comparison tools named by their crate names; Criterion as the harness; inputs from a small sample document up to a 190 megabyte GeoJSON file; and a sentence worth quoting in full, that where a tool lacks a feature the benchmark is skipped rather than faked. Then the end-to-end heading for the large file, an empty centred element, and links to an interactive report and to the methodology file. No timings appear on the page at all.
Reproducing a benchmark needs a remote submodule update and a large download
The task runner shows what a benchmark run actually costs. Running the benchmarks depends on a recipe that first updates all submodules, recursively and with the remote flag, which fetches the newest commit of each submodule rather than the pinned one, so two runs a week apart can measure different input code. It then checks for the large GeoJSON file and, if absent, downloads it from a third-party repository before the benchmark starts. Publishing the results is a separate recipe that imports the Criterion output directory into the project's GitHub Pages, which is the same host that serves the browser playground. So the reproducible path and the published path are both documented, and the first one depends on the network twice over.
The published crate leaves the evidence behind
The package manifest excludes a long list of directories and files from what is published: the workflows directory, the examples, the images, the benchmark directory, the tests, the task runner, the submodule file, the playground, the changelog, the contributing guide, three tool configuration files, the Nix files and the environment file. What ships is the library source and the manifests. That is a sensible default, and it has a consequence for anyone who installs from the registry rather than cloning: the benchmark methodology, the test suite and the playground are all absent from the copy they end up with, so the only place to check the performance claims is the web report or a clone. The manifest also describes the tool as inspired by a well-known path query syntax rather than as an implementation of it, which is a deliberate piece of positioning for a project whose whole argument is that it is not that thing.
Three renderings of a path across three examples
The path syntax is small, and the examples show four operators: a leading double star for a field under nested objects, a bracket wildcard for every element of an array, a parenthesised alternation for a field under either of two names, and a construct that matches any depth through both objects and arrays. What is inconsistent is how paths come back. The quick example queries with brackets attached to the field name and prints results with a dot before each bracket. The line-oriented example prints a bare bracket with no dot at all. The TOML example prints plain dotted keys with no brackets, because there are none. So the same tool renders the same concept three ways depending on format, and only the JSON cases carry the dot separator.
Every format is converted to JSON before the engine sees it
The multi-format section states the architecture in one sentence: non-JSON formats are converted to JSON at the boundary and then queried with the same engine, so queries work identically regardless of input. The examples confirm it, with a TOML manifest queried for dependency versions, a compose file queried for service images, and a line-oriented format where each line becomes an array element, which is why its output paths are indexed from zero with no field path in front. An explicit format flag exists for input from standard input or for files with unusual extensions. There is also a query that does nothing at all:
echo '{"name":"Ada","age":36}' | jg ''An empty string query prints the document formatted, which is the closest thing here to a pretty-printer, and the page compares it directly with the filter tool's identity filter.
Pedantic and nursery lints are denied, and the dev shell is Nix
The manifest sets a high bar for its own code: two whole clippy lint groups are denied rather than warned, a rule about doc paragraphs missing punctuation is a warning, and attributes that suppress lints are also a warning. The declared floor is Rust 1.88 on the 2024 edition. The root directory matches that seriousness with a clippy configuration, a licence and advisory checker configuration, a formatter configuration, a Nix flake with a lock file, an environment file for a directory-based tool, a task runner and a lock file, plus a submodule. Installation is offered through four package managers rather than one, which is unusually broad for a tool this size, and the Rust toolchain route is a single line:
cargo install jsongrepTwo library dependencies are worth noting for what they imply about large files: a memory-mapping crate and a borrowing JSON parser, alongside a glob matcher and a gitignore-aware walker for file selection.
Editorial conclusion
This is a small, well-documented tool with one decision you have to notice before you rely on its output. The defining feature is that every match carries its path, and the comparison section spends its best example on that, since printing the path is genuinely useful when you are exploring an unfamiliar document. The catch is stated in a parenthetical: when the output is piped, the path headers are hidden by default, and every comparison example on the page pipes through another command. Two other things to settle first. The published crate excludes the repository's own benchmarks, playground, tests and changelog, so an installed copy cannot show you the methodology behind the performance claims. And those claims are not on the page at all: the end-to-end section is a heading, an empty paragraph and two links, so the numbers live behind an interactive report that you would have to read before repeating any of them. The syntax itself is small enough to learn in a minute, and the four installer paths mean you can try it without committing to a package manager.
Frequently asked questions
What is jsongrep?
A Rust command-line tool and library for querying JSON, YAML, TOML, JSONL, CBOR and MessagePack documents with regular path expressions, so you describe which paths to match rather than how to transform. The query compiles to a deterministic finite automaton, and results carry the path they were found at. It is MIT licensed and installable through Homebrew, Winget, Scoop or cargo.
How does jsongrep differ from a jq-style filter pipeline?
The page compares four cases and gives both commands: finding a field at any depth, selecting several fields at once, counting matches, and pretty-printing. The recursive descent case is where the difference is largest, since the filter form needs a recursive operator plus null suppression while jsongrep has a flag that treats the query as a literal field name at any depth. jsongrep also prints where each match was found, though the page notes those path headers are hidden by default when output is piped.
What benchmarks does jsongrep publish?
Criterion benchmarks against three other query crates, in four groups that isolate parsing, query compilation, search and the full pipeline, on inputs from a small sample document to a 190 megabyte GeoJSON file. The page says a benchmark is skipped rather than faked where a tool lacks a feature. The actual timings are not on the page: the end-to-end section is a heading, an empty element and links to an interactive report and to the methodology file.
Can jsongrep read YAML and TOML with the same query syntax?
Yes, because non-JSON formats are converted to JSON at the boundary and then run through the same engine. The page queries a Cargo manifest for dependency versions and a compose file for service images with the same path syntax used for JSON, plus a line-oriented format where each line becomes an array element. An explicit format flag is available for standard input or unusual file extensions, and an empty query pretty-prints the document.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/micahkepe-jsongrep)