groxide
Query Rust crate documentation from the terminal. Works on the current crate, its dependencies, the stdlib, and any crate on crates.io.
[!WARNING] This project was built as an experiment in agentic engineering with heavy AI assistance. I didn't write the code by hand and I don't claim to understand every aspect of it. I came up with the idea, the general strategy, and the design plan. That being said, I've been using
groxdaily across several Rust projects and have tested it carefully. I plan to rewrite it by hand when I have time.
What it looks like
Inside a Rust project, query any dependency by path. Method lookup gets you signature, docs, and examples:
$ grox tokio::sync::Mutex::lock
fn tokio::sync::mutex::Mutex::lock
pub async fn lock(&self) -> MutexGuard<'_, T>
Locks this mutex, causing the current task to yield until the lock has
been acquired. When the lock has been acquired, function returns a
[MutexGuard].
If the mutex is available to be acquired immediately, then this call
will typically not yield to the runtime. However, this is not guaranteed
under all circumstances.
Cancel safety
This method uses a queue to fairly distribute locks in the order they
were requested. Cancelling a call to lock makes you lose your place in
the queue.
Examples
use tokio::sync::Mutex;
let mutex = Mutex::new(1);
let mut n = mutex.lock().await;
*n = 2;
Recursive listing shows what's in a module:
$ grox -r tokio::sync
tokio::sync:
struct tokio::sync::AcquireError pub struct AcquireError(_) [feature: sync]
struct tokio::sync::Barrier pub struct Barrier [feature: sync]
struct tokio::sync::Mutex pub struct Mutex<T: ?Sized> [feature: sync]
struct tokio::sync::Notify pub struct Notify [feature: sync]
struct tokio::sync::OnceCell pub struct OnceCell<T> [feature: sync]
struct tokio::sync::RwLock pub struct RwLock<T: ?Sized> [feature: sync]
struct tokio::sync::Semaphore pub struct Semaphore [feature: sync]
mod tokio::sync::broadcast pub mod broadcast [feature: sync]
mod tokio::sync::mpsc pub mod mpsc [feature: sync]
mod tokio::sync::oneshot pub mod oneshot [feature: sync]
...
It works outside a project too. Standard library queries and crates.io auto-fetch need no Cargo.toml:
$ grox std::collections::HashMap
struct std::collections::HashMap
pub struct HashMap<K, V, S = crate::hash::RandomState, A: Allocator = crate::alloc::Global>
A [hash map] implemented with quadratic probing and SIMD lookup.
By default, HashMap uses a hashing algorithm selected to provide
resistance against HashDoS attacks. ...
Methods:
pub fn capacity(&self) -> usize Returns the number of elements the map can hold ...
pub fn clear(&mut self) Clears the map, removing all key-value pairs.
pub fn contains_key<Q>(&self, k: &Q) -> bool Returns `true` if the map contains a value for ...
pub fn get<Q>(&self, k: &Q) -> Option<&V> Returns a reference to the value corresponding ...
pub fn insert(&mut self, k: K, v: V) -> Option<V> Inserts a key-value pair into the map.
...
Install
Or from source:
Requires Rust stable (MSRV 1.88) and a nightly toolchain for rustdoc JSON generation:
Agent skill
groxide ships with an agent skill that teaches AI coding agents how to use it.
For Claude Code:
For other agents (Codex, Cursor, Copilot, and 20+ others):
Usage
# Method docs
# Search across a crate's docs
# Source code with file path and line numbers
# Recursive listing of a module
# Brief skeleton (names only)
# Trait implementations (all)
# Trait implementations filtered to a specific trait
# JSON Lines output
# Pin to a specific version
# Wipe the cache
Reference
grox [OPTIONS] [PATH]
| Flag | Short | Description |
|---|---|---|
--brief |
-b |
Item names only |
--docs |
-d |
Full rendered documentation |
--source |
-s |
Source with file path and line numbers |
--search <QUERY> |
-S |
Full-text search (| for OR, space for AND) |
--kind <KIND> |
-k |
Filter by fn, struct, enum, trait, type, const, mod, macro |
--private |
-p |
Include non-public items |
--json |
-j |
JSON Lines |
--impls |
-i |
Trait implementations |
--impls-of <TRAIT> |
Filter trait implementations to one trait | |
--recursive |
-r |
List items recursively (composes with -b, -d, -s) |
--readme |
Crate README | |
--clear-cache |
Wipe the cache | |
--manifest-path <PATH> |
Path to Cargo.toml |
|
--features <FEATURES> |
Comma-separated features | |
--all-features |
All features | |
--no-default-features |
Skip the default feature |
-d and -s compose: grox -d -s path shows source with full docs. -j, -p, and -k are orthogonal and combine with any mode.
Exit codes: 0 success, 1 not found, 2 error.
How it works
- Resolve the crate: current project, dependency, workspace member, transitive dep, stdlib, or crates.io auto-fetch.
- Generate rustdoc JSON via
cargo +nightly rustdoc --output-format json. - Build a queryable index from the JSON.
- Cache the index to disk. Current crate caches live in
<workspace_target>/groxide/<crate>.groxide(invalidated whenCargo.toml,src/**/*.rs, orbuild.rschange). Dependency, stdlib, and external caches live under~/.cache/groxide/keyed on version (deps), toolchain hash (stdlib), or version (external). Feature flags and--privateare hashed into the filename so they don't collide. - Query through a 5-stage pipeline: exact path, case-insensitive, suffix match, name match, not found.
- Render plain text with smart defaults per item kind, truncated to ~1500 chars.
Inside vs outside a Rust project
Inside a project (directory with Cargo.toml), grox reads the project's dependency graph. Running grox with no arguments shows the current crate's docs. Queries resolve through: current crate, direct dependencies, workspace members, transitive dependencies, stdlib, then crates.io auto-fetch. Each step matches by exact name (with -/_ equivalence): grox candle in a workspace whose only members are candle-pitch and candle-crepe falls through to a crates.io fetch of candle. Use the full member name to target a workspace crate.
Outside a project, only stdlib queries and crates.io auto-fetch work. Running grox with no arguments errors out (no current crate). The cache for external crates lives in ~/.cache/groxide/.
Output for agents
All documentation content goes to stdout. All status messages go to stderr. This separation matters for LLM agents: they pipe stdout into context and ignore stderr.
Status messages are prefixed with [grox]:
[grox] Building index for tokio 1.40.0...
[grox] Building index for tokio 1.40.0... done (2.3s)
Security
grox invokes cargo +nightly rustdoc on crate source. This runs the crate's build.rs and any proc macros it depends on; same code execution as cargo build, but not the same as cargo install (no built binary is executed).
Auto-fetch matters: when you query a crate that isn't already a dependency (e.g. grox some-random-crate), grox downloads it from crates.io and compiles it. If you wouldn't add it to Cargo.toml, don't query it. Pin a version (grox crate@1.2.3) if you want reproducibility.
Contributing
See CONTRIBUTING.md.
License
Dual-licensed under MIT or Apache-2.0, at your option.