rmap
Codebase map CLI. Compact, parsed, friendly to humans and LLM tooling.

Rust-aware today.
tree(no--detail) works on any repo. Item parsing,refs,deps, andgraphare Rust-only — they usesynto read.rsfiles. Other languages render as bare file names.
Path enumeration is git-aware via git ls-files and respects .gitignore. Outside a git work tree, rmap falls back to a filesystem walk that skips .git, target, node_modules, .DS_Store, tmp, dist.
Install
From source:
Subcommands
| Command | Purpose | Rust-only? |
|---|---|---|
tree |
Brace map of files/dirs. --detail inlines parsed items. |
No (items: yes) |
module |
Focused index of a subtree or file, items always inlined. | Items: yes |
refs |
Find defs + uses of one or more identifiers. | Yes |
deps |
File-level dep graph from use and mod statements. |
Yes |
graph |
Reachability subgraph from an entry file (forward or reverse). | Yes |
Quick start
Orient on an unfamiliar repo:
Drill into a subtree or file:
Find an identifier:
Trace dependencies:
Output samples
rmap tree --detail:
src {
main.rs { struct Cli, enum Cmd, fn main, fn run_tree, fn run_module }
parse.rs { struct ParseOptions, fn render_file, fn render_str, fn render_items }
walk.rs {
const SKIP_DIRS, enum Node { fn name }, struct Filter,
fn enumerate, fn list_paths, fn git_ls_files
}
}
rmap tree --detail --lines:
walk.rs:249 { const SKIP_DIRS:12-19, enum Node:21-32 { fn name:35-39 },
struct Filter:42-50, fn enumerate:52-79, ... }
rmap refs Filter:
src/main.rs:396:24 use struct-lit Filter
src/refs.rs:28:25 use import Filter
src/walk.rs:37:12 def struct Filter
src/walk.rs:47:40 use type Filter
rmap refs Filter --excerpt 1 (with source context):
src/walk.rs:37:12 def struct Filter
36 | #[derive(Default)]
> 37 | pub struct Filter {
38 | /// Skip paths whose relative path contains any of these substrings.
rmap refs Filtr (typo → suggestion):
no hits for `Filtr`
did you mean: Filter, filter?
rmap deps src/walk.rs:
src/walk.rs
out: -
in: src/refs.rs, src/render.rs
rmap graph --depth 2:
src/main { deps, graph { deps* }, parse, refs { walk }, render { parse*, walk* }, walk* }
Markers: * revisit, ~ back-edge, {…} depth limit hit.
Non-Rust repos
rmap still works — with reduced fidelity:
tree(no--detail) — full layout, language-agnostic.tree --detail,module— non-.rsfiles render as bare names.refs,deps,graph— Rust-only. Run on a Rust repo or scope with--in.
Teach an AI agent
Prints a short markdown snippet telling Claude/Cursor/Codex/... to reach for rmap instead of find/ls/tree when locating code.
Flags reference
Run rmap --help for the full surface. Highlights:
tree
--depth N,--detail,--lines--cap PREFIX=N(repeatable, defaultdocs/sessions=10),--no-default-caps--exclude SUBSTR(repeatable),--ext rs,md--detailimplicitly caps depth at 4 unless--depthis given.
module
--depth N,--lines,--ext rs,md- Positional args: exact dir, exact file, or unique path suffix. Multiple args render in order, blank line between.
refs <NAME>...
--in PATH,--defs-only,--uses-only,--excerpt N- Output:
file:line:col role kind name.role∈def|use. --excerpt Nappends ±N source lines around each hit; the hit line is marked>.defkinds:fn, method, struct, enum, union, trait, const, static, type, macro.usekinds:call, method, type, struct-lit, path, macro, import, pat.- Matches by trailing path segment only — no name resolution. Scope with
--in PATHto disambiguate. - On zero hits, suggests similar identifiers (
did you mean: ...) ranked by substring, snake/camelCase token overlap, longest common prefix, character-bigram Jaccard similarity, and edit distance. A signal gate suppresses short-edit-distance noise (e.g.Barwon't be suggested forbaner).
deps [PATH]
--reverse,--extPATHselects scope: dir withCargo.toml(whole repo), subdirectory (scoped subtree, repo auto-detected), or.rsfile (focus mode: in/out/ext).- Whole-repo / scoped output:
file -> dep1, dep2, .... - Resolves
crate::,self::,super::against themodtree fromsrc/main.rsorsrc/lib.rs. Single-crate only — workspaces not parsed.
graph [ENTRY...]
--reverse,--mermaid,--depth N,--ext- Zero or more entries (each renders its own subgraph; default = detected crate root).
- Default output: single-line brace tree. Reuses the
depsgraph and followsmod x;edges too.
Conventions
- Output is plain text on stdout; errors go to stderr with non-zero exit.
- No colors, no panics on user input.
- Item parsing is Rust-only (via
syn).
License
MIT. See LICENSE.