Help us improve
Share bugs, ideas, or general feedback.
Fast indexed code search tools for Claude Code
npx claudepluginhub qhkm/fastripgrepFast indexed code search — 5x faster than ripgrep using sparse n-gram indexing
Share bugs, ideas, or general feedback.
frg (fastripgrep) builds a sparse n-gram index of your codebase, then searches in 10ms instead of scanning every file. Inspired by Cursor's fast regex search.
$ frg index . # one-time: ~20s for 9K files
$ frg "renderUsage" # 10ms (ripgrep: 53ms)
Tested on openclaw (9,000 files), case-sensitive, warm cache, output to /dev/null:
| Pattern | Type | grep | ripgrep | frg | vs rg |
|---|---|---|---|---|---|
renderUsage | selective | 1,553ms | 53ms | 10ms | 5.3x |
useState|useEffect | alternation | 962ms | 54ms | 13ms | 4.2x |
.* | wildcard | — | 197ms | 74ms | 2.7x |
TODO|FIXME|HACK|XXX|BUG | multi-alt | — | 53ms | 21ms | 2.5x |
import.*from.*react | regex | 1,080ms | 84ms | 50ms | 1.7x |
x | single byte | — | 102ms | 59ms | 1.7x |
function (24K hits) | broad | 398ms | 75ms | 51ms | 1.5x |
^\s*export\s | anchored | — | 72ms | 68ms | 1.06x |
frg wins on all 8 pattern types. 100% match count parity with ripgrep.
Match struct allocation for millions of results)brew install qhkm/tap/frg
curl -fsSL https://raw.githubusercontent.com/qhkm/fastripgrep/main/install.sh | sh
cargo install fastripgrep
git clone https://github.com/qhkm/fastripgrep
cd fastripgrep
cargo build --release
# Binary at target/release/frg
# Build the index (one-time, re-run after major changes)
frg index [path]
# Search (uses index if available)
frg search <pattern> [path]
# Rebuild index
frg update [path]
# Show index stats
frg status [path]
# Find a specific function
frg search "handleExport" .
# Regex with alternation
frg search "useState|useEffect" .
# Case-insensitive
frg search -i "config" .
# Smart case (lowercase = insensitive, mixed = sensitive)
frg search -S "config" . # matches Config, CONFIG, config
frg search -S "Config" . # matches Config only
# Fixed string (no regex interpretation)
frg search -F '${variable}' .
# Files only
frg search -l "TODO" .
# Count matches per file
frg search -c "function" .
# Context lines
frg search -C 3 "error" .
# Filter by file type
frg search --type ts "import" .
# JSON output
frg search --json "pattern" .
# Brute force (skip index, like ripgrep)
frg search -n "pattern" .
| Flag | Description |
|---|---|
-i | Case-insensitive |
-S / --smart-case | Case-insensitive if pattern is all lowercase |
-F / --literal | Treat pattern as fixed string |
-l | Files-with-matches only |
-c / --count | Show match count per file |
-C <n> / --context <n> | Show surrounding lines |
-m <n> / --max-count <n> | Limit results per file |
-q / --quiet | Suppress output, exit code only |
-n / --no-index | Brute-force scan (no index) |
--glob <pattern> | Filter files by glob |
--type <ext> | Filter by file extension |
--json | Output as JSON |
frg supports a config file with default arguments, like ripgrep.
Location: ~/.frgrc or $FRG_CONFIG_PATH
Format: One argument per line. # comments. Empty lines ignored.
# ~/.frgrc
# Smart case by default
--smart-case
grep and ripgrep scan every file on every search. frg builds an index once and uses it to skip 99% of files:
| Approach | Strategy | Time on 9K files |
|---|---|---|
| grep | Scan all files, match regex | ~1,000ms |
| ripgrep | Scan all files, SIMD regex | ~50-100ms |
| frg | Index lookup + read ~5 files | ~10-70ms |
frg uses sparse n-grams — variable-length byte substrings selected by a deterministic weight function. This is the approach described in Cursor's blog post.