Exact grep when you know the text. Fuzzy grep when you almost do.
Why · Quick Start · Highlights · How Fuzzy Search Works · Indexing · Testing · Contributing
rocketgrep is a Rust command-line search tool inspired by ripgrep. It searches code and text quickly, and it also supports approximate matching with Levenshtein edit distance through -k/--edit-distance.
If you search for the wrong spelling:
rocketgrep -k 1 "neddle" .rocketgrep can still find needle, because it is one edit away.
Classic grep tools are excellent when you know the exact text or regex. Real code search is often messier.
You might half-remember an identifier. A symbol might have been renamed. Generated code might contain noisy variants. Or you might simply typo a function name while moving fast.
rocketgrep explores that space: keep exact search fast, then add native fuzzy search that works directly in the terminal.
- Fast exact search — regex search by default and fixed-string search with
-F. - Native fuzzy search — use
-k 1,-k 2, or another edit-distance threshold. - Developer-project aware — respects
.gitignore, hidden-file rules, globs, and file types. - Parallel scanning — walks and searches files using Rayon-powered parallelism.
- Memory-mapped IO — uses
memmap2when possible with a normal-read fallback. - Useful output modes — context lines, colors, counts, files-with-matches, scores, ranking, and JSON.
- Sparse indexing — optional trigram index for repeated exact or fuzzy searches.
- Research path included — PILLAR-style primitives and seaweed-monoid scaffolding are present for future algorithm work.
Install from crates.io:
cargo install rocketgrep
rocketgrep --versionThat is the recommended install path for most users.
Build from source:
git clone https://github.com/priceds/rocketgrep.git
cd rocketgrep
cargo build --releaseRun the binary:
target/release/rocketgrep --versionOn Windows:
target\release\rocketgrep.exe --versionSearch with a regex:
cargo run --bin rocketgrep -- "fn main" srcSearch for an exact string:
cargo run --bin rocketgrep -- -F "literal_needle" .Search with one allowed edit:
cargo run --bin rocketgrep -- -k 1 "neddle" .Show fuzzy scores and rank better matches first:
cargo run --bin rocketgrep -- -k 1 --scores --sort score "needle" .Emit newline-delimited JSON:
cargo run --bin rocketgrep -- --json -k 1 "needle" srcAt a high level, rocketgrep has four moving parts.
1. Walk the project. It uses the Rust ignore crate, so it understands .gitignore, hidden files, file types, globs, and common developer-project rules.
2. Read files efficiently. It uses memory-mapped IO through memmap2 when possible and falls back to normal file reads when mapping fails.
3. Choose a matcher. Regex search uses Rust's byte-oriented regex engine. Fixed-string search uses fast byte substring search. Fuzzy search uses a practical edit-distance pipeline.
4. Render results. Output can be human-readable, colored, scored, ranked, counted, or emitted as newline-delimited JSON.
For approximate search, rocketgrep currently uses a pragmatic algorithm:
- Split the pattern into smaller exact pieces.
- Search quickly for those pieces.
- Use those hits to guess candidate match locations.
- Verify each candidate with bounded Levenshtein distance.
- Keep the best non-overlapping matches and attach a score.
This works well for many developer searches because identifiers and code tokens usually contain selective substrings.
For very short patterns or weak filters, rocketgrep can fall back to a direct dynamic-programming check. That is slower, but safer.
rocketgrep is inspired by:
"Faster Pattern Matching under Edit Distance" by Panagiotis Charalampopoulos, Tomasz Kociumaka, and Philip Wellnitz.
- arXiv abstract: https://arxiv.org/abs/2204.03087
- PDF: https://arxiv.org/pdf/2204.03087.pdf
The paper develops a faster theoretical algorithm for pattern matching under edit distance using the PILLAR model, periodicity, Dynamic Puzzle Matching, and the seaweed monoid.
Important honesty note: rocketgrep does not yet claim to fully implement the entire paper. The current release uses a practical fuzzy-search engine designed for real CLI use, while also including early PILLAR-style primitives and seaweed-monoid scaffolding for future research-backed work.
Build a sparse trigram index for repeated searches:
cargo run --bin rocketgrep -- index -o .rocketgrep-index.json .Use it for exact or fuzzy search:
cargo run --bin rocketgrep -- -F --index .rocketgrep-index.json "needle" .
cargo run --bin rocketgrep -- -k 1 --index .rocketgrep-index.json "needle" .The index is only a prefilter. Every result is still checked by the real matcher, so broad index hits cannot create false matches. Files missing from the index or changed since indexing are scanned normally.
- The full theoretical algorithm from the paper is not implemented yet.
- Fuzzy search is literal-pattern based, not fuzzy regex.
- Very short fuzzy patterns can be expensive.
- Highly repetitive text can create many candidate matches.
- The CLI is not yet fully compatible with every
ripgrepflag.
Current verification:
cargo test --all
20 library tests passed, 6 CLI integration tests passed
cargo build --release --bin rocketgrep
release build passed
The tests cover exact literal search, regex search, approximate one-error search, ASCII-insensitive fuzzy search, context output, JSON score metadata, .gitignore handling, binary-file skipping, sparse index filtering, stale-index safety, PILLAR primitives, and seaweed monoid laws.
We also ran small warm-cache smoke benchmarks on Windows using Measure-Command. These are not a replacement for hyperfine, but they are useful early signal.
Environment:
- OS: Windows
ripgrep:15.1.0rocketgrep: release build- Output redirected to null
- Cache state: warm local filesystem
Small repo search over src, pattern fn:
| Command | Average | Minimum | Maximum |
|---|---|---|---|
rocketgrep -F fn src |
15.52ms |
12.50ms |
51.05ms |
rg -F fn src |
23.33ms |
21.07ms |
40.03ms |
rocketgrep fn src |
14.03ms |
12.45ms |
26.58ms |
rg fn src |
23.39ms |
19.54ms |
38.78ms |
Synthetic 2000-file corpus, pattern needle:
| Command | Average | Minimum | Maximum |
|---|---|---|---|
rocketgrep -F needle corpus |
54.39ms |
49.47ms |
77.21ms |
rg -F needle corpus |
103.18ms |
96.59ms |
109.34ms |
rocketgrep needle corpus |
54.77ms |
49.75ms |
66.67ms |
rg needle corpus |
100.22ms |
93.72ms |
109.82ms |
rocketgrep -k 1 neodle corpus |
56.21ms |
51.27ms |
68.78ms |
These results are encouraging: rocketgrep was faster than ripgrep in these simple local exact-search cases, and fuzzy -k 1 was close to exact-search time on the synthetic corpus. They are not a universal performance claim. Larger real-world benchmarks are still needed across cold cache, huge monorepos, complex regexes, binary-heavy trees, massive output, Linux/macOS, and adversarial fuzzy cases.
We also reproduced the shape of the benchmark shown in the ripgrep README: search a kernel-like tree for word matches of [A-Z]+_SUSPEND. The original benchmark uses a real built Linux kernel tree on Linux hardware. This reproduction uses a generated C/H corpus on Windows, so treat it as local signal, not a replacement for the original benchmark.
Local setup:
- OS: Windows
- Corpus: generated kernel-like C/H tree under
C:\tmp - Pattern:
[A-Z]+_SUSPEND - Runs: 20 measured runs after warmup
- Timing tool: PowerShell
Measure-Command - Output: redirected to null
- Missing tools:
ackwas not installed;hypergreprelease artifact was Linux-only in this environment
Tool colors:
rocketgrep ripgrep ugrep git grep ag / grep
Default ignore-aware search:
| Tool | Command | Lines | Average | Minimum | Maximum |
|---|---|---|---|---|---|
| ugrep | ugrep -r --ignore-files --no-hidden -I -w '[A-Z]+_SUSPEND' |
536 | 42.01ms |
39.63ms |
52.90ms |
| rocketgrep | rocketgrep '\b[A-Z]+_SUSPEND\b' |
536 | 64.98ms |
60.92ms |
71.76ms |
| git grep | git grep -P -n -w '[A-Z]+_SUSPEND' |
536 | 68.86ms |
65.92ms |
75.33ms |
| git grep | git grep -E -n -w '[A-Z]+_SUSPEND' |
536 | 69.30ms |
67.05ms |
72.23ms |
| ripgrep | rg -n -w '[A-Z]+_SUSPEND' |
536 | 84.02ms |
77.46ms |
91.53ms |
| ag | ag --nocolor -w '[A-Z]+_SUSPEND' |
536 | 137.46ms |
132.08ms |
147.58ms |
Whitelist / no-ignore C-H search:
| Tool | Command | Lines | Average | Minimum | Maximum |
|---|---|---|---|---|---|
| ugrep | ugrep -r -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND' |
736 | 50.80ms |
49.16ms |
56.14ms |
| rocketgrep | rocketgrep --no-ignore --hidden --text -t c '\b[A-Z]+_SUSPEND\b' |
736 | 83.65ms |
77.82ms |
89.31ms |
| ripgrep | rg -uuu -tc -n -w '[A-Z]+_SUSPEND' |
736 | 89.91ms |
87.14ms |
93.36ms |
| Git grep.exe | grep -E -r -n --include='*.c' --include='*.h' -w '[A-Z]+_SUSPEND' |
736 | 355.91ms |
345.35ms |
364.69ms |
In this local reproduction, ugrep was fastest overall. rocketgrep was faster than ripgrep in both tested modes, and landed close to git grep in the default ignore-aware search. The result is promising, but still only one benchmark on one Windows machine.
If you have hyperfine and ripgrep installed:
benchmarks/hyperfine_rocketgrep.ps1 -Corpus C:\path\to\repo -Pattern needleUseful comparisons:
rocketgrep -Fvsrg -F.rocketgrepregex mode vsrg.rocketgrep -k 1androcketgrep -k 2on real typo/symbol-search workloads.- Indexed vs non-indexed repeated searches.
Contributions are welcome.
Especially useful contributions:
- Real benchmark reports from large repositories.
- More
ripgrep-compatible CLI flags. - Better fuzzy matching for short or repetitive patterns.
- Linux and macOS testing.
- JSON schema documentation.
- A faithful CKW-inspired backend behind a separate algorithm flag.
For algorithmic changes, please include tests against a simple dynamic-programming verifier. Search tools must be especially careful about false negatives.
