Search Tools Mastery: Combining rg, grepai, Serena & ast-grep
Search Tools Mastery: Combining rg, grepai, Serena & ast-grep
Section titled “Search Tools Mastery: Combining rg, grepai, Serena & ast-grep”Master the art of code search by combining the right tools for maximum efficiency
Author: Florian BRUNIAUX | Contributions from Claude (Anthropic) Reading time: ~20 minutes Last updated: January 2026
Table of Contents
Section titled “Table of Contents”- Quick Reference Matrix
- Tool Comparison
- Decision Tree
- Combined Workflows
- Real-World Scenarios
- Performance Optimization
- Common Pitfalls
Quick Reference Matrix
Section titled “Quick Reference Matrix”| I need to… | Use This Tool | Command Example |
|---|---|---|
| Find exact text | rg (Grep tool) | rg "authenticate" --type ts |
| Find by meaning | grepai | grepai search "user login flow" |
| Find function definition | Serena | serena find_symbol --name "login" |
| Find structural pattern | ast-grep | ast-grep "async function $F" |
| See who calls function | grepai | grepai trace callers "login" |
| Get file structure | Serena | serena get_symbols_overview |
| Refactor across files | Serena + ast-grep | Combined workflow |
| Explore unknown codebase | grepai → Serena | Discovery pattern |
Tool Comparison
Section titled “Tool Comparison”Complete Feature Matrix
Section titled “Complete Feature Matrix”| Feature | rg (ripgrep) | grepai | Serena | ast-grep |
|---|---|---|---|---|
| Search Type | Regex/text | Semantic (meaning) | Symbol-aware | AST structure |
| Technology | Pattern matching | Embeddings (Ollama) | Symbol parsing | Abstract Syntax Tree |
| Speed | ⚡ ~20ms | 🐢 ~500ms | ⚡ ~100ms | 🕐 ~200ms |
| Setup | ✅ None (built-in) | ⚠️ Ollama + install | ⚠️ MCP config | ⚠️ npm install |
| Integration | ✅ Native (Grep) | ⚠️ MCP server | ⚠️ MCP server | ⚠️ Plugin |
| Privacy | ✅ 100% local | ✅ 100% local | ✅ 100% local | ✅ 100% local |
| Context needed | None | None | Project indexation | None |
| Languages | All (text) | All | TS/JS/Py/Rust/Go | TS/JS/Py/Rust/Go/C++ |
| Call graph | ❌ No | ✅ Yes | ❌ No | ❌ No |
| Symbol tracking | ❌ No | ❌ No | ✅ Yes | ❌ No |
| Session memory | ❌ No | ❌ No | ✅ Yes | ❌ No |
| False positives | Medium | Low | Very low | Very low |
| Learning curve | Low | Medium | Low | High |
Token Cost Comparison
Section titled “Token Cost Comparison”| Tool | Typical Query | Tokens Consumed | Results Returned |
|---|---|---|---|
| rg | ”authenticate” | ~500 | Exact matches only |
| grepai | ”auth flow” | ~2000 | Intent-based matches |
| Serena | find_symbol | ~1000 | Symbol + context |
| ast-grep | AST pattern | ~1500 | Structural matches |
Key insight: rg is 4x more token-efficient but 10x less intelligent than semantic tools.
Decision Tree
Section titled “Decision Tree”Level 1: What Do You Know?
Section titled “Level 1: What Do You Know?”Do you know the EXACT text/pattern?│├─ YES → Use rg (ripgrep)│ ├─ Known function name: rg "createSession"│ ├─ Known import: rg "import.*React"│ └─ Known pattern: rg "async function"│└─ NO → Go to Level 2Level 2: What Are You Looking For?
Section titled “Level 2: What Are You Looking For?”What's your search intent?│├─ "Find by MEANING/CONCEPT"│ → Use grepai│ └─ Example: grepai search "payment validation logic"│├─ "Find FUNCTION/CLASS definition"│ → Use Serena│ └─ Example: serena find_symbol --name "UserController"│├─ "Find by CODE STRUCTURE"│ → Use ast-grep│ └─ Example: async without error handling│└─ "Understand DEPENDENCIES" → Use grepai trace └─ Example: grepai trace callers "validatePayment"Level 3: Optimization
Section titled “Level 3: Optimization”Found too many results?│├─ rg → Add --type filter or narrow path├─ grepai → Add --path filter or use trace├─ Serena → Filter by symbol type (function/class)└─ ast-grep → Add constraints to patternCombined Workflows
Section titled “Combined Workflows”Workflow 1: Exploring Unknown Codebase
Section titled “Workflow 1: Exploring Unknown Codebase”Goal: Understand a new project quickly
Step-by-step:
# 1. SEMANTIC DISCOVERY (grepai)# Find files related to authenticationgrepai search "user authentication and session management"# → Output: auth.service.ts, session.middleware.ts, user.controller.ts
# 2. STRUCTURAL OVERVIEW (Serena)# Understand each file's structureserena get_symbols_overview --file auth.service.ts# → Output:# - class AuthService# - login(email, password)# - logout(sessionId)# - validateSession(token)
# 3. DEPENDENCY MAPPING (grepai trace)# See how login is usedgrepai trace callers "login"# → Output: Called by UserController, ApiGateway, AdminPanel
# 4. EXACT SEARCH (rg)# Find specific implementation detailsrg "validateSession" --type ts -A 5# → Output: Full function with 5 lines of contextResult: Complete understanding in 4 commands (vs 30+ file reads)
Workflow 2: Large-Scale Refactoring
Section titled “Workflow 2: Large-Scale Refactoring”Goal: Rename createSession → initializeUserSession across 50+ files
Step-by-step:
# 1. IMPACT ANALYSIS (grepai trace)# Understand full scopegrepai trace callers "createSession"# → Output: 47 callers across 23 filesgrepai trace callees "createSession"# → Output: Calls validateUser, createToken, storeSession
# 2. STRUCTURAL VALIDATION (ast-grep)# Ensure consistent usage patternast-grep "createSession($$$ARGS)"# → Output: All invocations with their argument patterns
# 3. SYMBOL-AWARE REFACTORING (Serena)# Precise renamingserena find_symbol --name "createSession" --include-body true# → Get exact definition + all references
serena replace_symbol_body \ --name "createSession" \ --new-name "initializeUserSession"# → Rename across all files maintaining structure
# 4. VERIFICATION (rg)# Confirm no old references remainrg "createSession" --type ts# → Should return 0 resultsResult: Safe refactoring with full dependency awareness
Workflow 3: Security Audit
Section titled “Workflow 3: Security Audit”Goal: Find security vulnerabilities
Step-by-step:
# 1. SEMANTIC DISCOVERY (grepai)# Find security-sensitive codegrepai search "SQL query construction"grepai search "user input validation"grepai search "password handling"
# 2. STRUCTURAL PATTERNS (ast-grep)# Find specific vulnerability patterns
# SQL injection risksast-grep 'db.query(`${$VAR}`)'
# XSS risksast-grep 'innerHTML = $VAR'
# Missing error handlingast-grep -p 'async function $F($$$) { $$$BODY }' \ --without 'try { $$$TRY } catch'
# 3. DEPENDENCY TRACING (grepai)# See where vulnerable code is calledgrepai trace callers "executeQuery"# → Identify all entry points
# 4. EXACT VERIFICATION (rg)# Confirm findingsrg "innerHTML\s*=" --type tsrg "password" --type ts | rg -v "hashed"Result: Comprehensive security audit in minutes
Real-World Benchmarks
Section titled “Real-World Benchmarks”grepai vs grep (Janvier 2026)
Section titled “grepai vs grep (Janvier 2026)”Contexte: Benchmark sur Excalidraw (155k lignes TypeScript) Auteur: YoanDev (mainteneur de grepai - biais potentiel) Méthodologie: 5 questions de découverte de code identiques
| Métrique | grep | grepai | Différence |
|---|---|---|---|
| Tool calls | 139 | 62 | -55% |
| Input tokens | 51k | 1.3k | -97% |
À retenir: Recherche sémantique réduit drastiquement les tokens en identifiant les fichiers pertinents dès la première tentative, évitant l’exploration itérative.
Limitations:
- Benchmark par le mainteneur de l’outil
- Single-project validation (TypeScript only)
- Pas de validation indépendante à ce jour
Source: yoandev.co/grepai-benchmark
Note: Ce benchmark reflète l’état de janvier 2026. Les performances peuvent évoluer avec les mises à jour de Claude Code et grepai.
Workflow 4: Framework Migration
Section titled “Workflow 4: Framework Migration”Goal: Migrate React class components → hooks
Step-by-step:
# 1. INVENTORY (ast-grep)# Find all class componentsast-grep 'class $C extends React.Component'# → Output: 34 components to migrate
# 2. DEPENDENCY ANALYSIS (grepai)# Understand component relationshipsfor component in $(ast-grep 'class $C extends' --json | jq -r '.[].name'); do grepai trace callers "$component"done# → Build migration order (leaf components first)
# 3. PATTERN DETECTION (ast-grep)# Identify lifecycle methods usedast-grep 'componentDidMount() { $$$BODY }'ast-grep 'componentWillReceiveProps($$$) { $$$BODY }'# → Map to equivalent hooks
# 4. INCREMENTAL MIGRATION (Serena + ast-grep)# Migrate one component at a timeserena find_symbol --name "UserProfile" --include-body true# → Get full component code
# Use ast-grep to transformast-grep --rewrite \ --from 'class $C extends React.Component' \ --to 'const $C = () => { }'
# 5. VERIFICATION (rg + grepai)# Ensure migration successfulrg "React.Component" --type tsx # Should decreasegrepai search "component lifecycle methods" # Find any missedResult: Systematic migration with minimal breakage
Workflow 5: Performance Optimization
Section titled “Workflow 5: Performance Optimization”Goal: Identify and fix performance bottlenecks
Step-by-step:
# 1. HOTSPOT DISCOVERY (grepai)# Find performance-critical codegrepai search "heavy computation or loops"grepai search "database queries in loops"
# 2. PATTERN DETECTION (ast-grep)# Find N+1 query patternsast-grep 'for ($$$) { await db.query($$$) }'
# Find missing memoizationast-grep 'useMemo' --invert-match \ --in 'const $VAR = $$$'
# 3. CALL GRAPH ANALYSIS (grepai trace)# Find hot pathsgrepai trace graph "renderUserList" --depth 3# → Visualize dependency tree
# 4. SYMBOL TRACKING (Serena)# Track function changesserena write_memory "perf_baseline" \ "renderUserList: 450ms avg"
# After optimizationserena write_memory "perf_optimized" \ "renderUserList: 45ms avg (10x improvement)"
# 5. VERIFICATION (rg)# Confirm optimizations appliedrg "useMemo|useCallback" --type tsxResult: Data-driven performance improvements
Real-World Scenarios
Section titled “Real-World Scenarios”Scenario 1: “I Don’t Know What I’m Looking For”
Section titled “Scenario 1: “I Don’t Know What I’m Looking For””Problem: New project, no documentation, need to add feature
Solution: Semantic-first discovery
# Start broad with meaninggrepai search "user profile management"# → Discover relevant files
# Then narrow with structureserena get_symbols_overview --file user-profile.service.ts# → Understand available functions
# Finally, exact search for detailsrg "updateProfile" --type ts -C 3Scenario 2: “This Function is Called from Everywhere”
Section titled “Scenario 2: “This Function is Called from Everywhere””Problem: Need to modify a function but worried about breaking things
Solution: Dependency mapping first
# 1. See all callersgrepai trace callers "calculateTotal"# → 47 callers found
# 2. Analyze caller contextsfor file in $(grepai trace callers "calculateTotal" --json | jq -r '.[].file'); do serena get_symbols_overview --file "$file"done
# 3. Identify safe vs risky call sitesast-grep 'calculateTotal($ARGS)' --json# → Group by argument patterns
# 4. Make change with confidence# Now you know all impact pointsScenario 3: “Find All Code Doing X”
Section titled “Scenario 3: “Find All Code Doing X””Problem: Need to apply consistent pattern across codebase
Solution: Combine semantic + structural
# Example: Find all error handling code
# 1. Semantic discoverygrepai search "error handling and exception management"
# 2. Structural patternsast-grep 'try { $$$TRY } catch ($ERR) { $$$CATCH }'ast-grep 'throw new Error($MSG)'
# 3. Verify consistencyrg "catch\s*\(" --type ts | wc -l# Compare with ast-grep count to find anomaliesScenario 4: “I Need to Understand This Module”
Section titled “Scenario 4: “I Need to Understand This Module””Problem: Complex module with unclear responsibilities
Solution: Multi-tool analysis
# 1. Get symbol overview (Serena)serena get_symbols_overview --file payment.module.ts# → See all exports, classes, functions
# 2. Understand dependencies (grepai)grepai trace callees "PaymentModule"# → What does this module use?
grepai trace callers "PaymentModule"# → Who uses this module?
# 3. Find implementation patterns (ast-grep)ast-grep 'export class $C' --file payment.module.tsast-grep 'async $METHOD($$$)' --file payment.module.ts
# 4. Read specific implementations (rg)rg "processPayment" --type ts -A 20Performance Optimization
Section titled “Performance Optimization”Choosing the Fastest Tool
Section titled “Choosing the Fastest Tool”General Rules:
- Known exact text → Always use rg first
- Unknown exact text → Use grepai, then rg for verification
- Refactoring → Serena for symbol safety
- Large migrations → ast-grep for structural precision
Performance Benchmarks
Section titled “Performance Benchmarks”Test: Find authentication code in 500k line codebase
| Strategy | Time | Results Quality |
|---|---|---|
| rg “auth” only | 0.2s | 5000+ false positives |
| grepai “auth” only | 2.5s | 50 relevant results |
| grepai → rg (combined) | 2.7s | 50 relevant, verified |
| Serena symbols only | 1.5s | 12 auth functions |
| ast-grep patterns | 3.0s | 8 auth flows |
Winner: Serena symbols (fastest + high quality) for known function names
Parallelization Strategy
Section titled “Parallelization Strategy”For large codebases (>100k lines):
# Run searches in parallel
# Terminal 1: Semantic discoverygrepai search "authentication flow" > /tmp/grepai-results.json &
# Terminal 2: Symbol indexingserena get_symbols_overview --file src/**/*.ts > /tmp/symbols.json &
# Terminal 3: Pattern detectionast-grep 'async function $F' --json > /tmp/ast-results.json &
# Wait for all, then combine resultswaitjq -s '.[0] + .[1] + .[2]' \ /tmp/grepai-results.json \ /tmp/symbols.json \ /tmp/ast-results.jsonCommon Pitfalls
Section titled “Common Pitfalls”Pitfall 1: Using Semantic Search for Exact Matches
Section titled “Pitfall 1: Using Semantic Search for Exact Matches”❌ Wrong:
grepai search "createSession" # Slow, overkill✅ Right:
rg "createSession" --type ts # Fast, preciseRule: If you know the exact text, never use semantic search.
Pitfall 2: Using rg for Conceptual Search
Section titled “Pitfall 2: Using rg for Conceptual Search”❌ Wrong:
rg "auth.*login.*session" --type ts # Misses variations✅ Right:
grepai search "authentication and session management"Rule: Regex doesn’t understand meaning, use semantic tools.
Pitfall 3: Ignoring Call Graph Before Refactoring
Section titled “Pitfall 3: Ignoring Call Graph Before Refactoring”❌ Wrong:
# Directly refactor without checking callersrg "oldFunction" --type ts | sed 's/oldFunction/newFunction/g'✅ Right:
# Check impact firstgrepai trace callers "oldFunction"# See 47 callers across 23 files# Then plan refactoring strategyRule: Always trace dependencies before modifying shared code.
Pitfall 4: Not Combining Tools
Section titled “Pitfall 4: Not Combining Tools”❌ Wrong:
# Use only one tool for complex taskast-grep 'async function $F' --json | jq '.[].file' | xargs -I {} vim {}# Blindly edit without understanding context✅ Right:
# Combine for full understandingast-grep 'async function $F' --json > /tmp/async.jsonfor file in $(jq -r '.[].file' /tmp/async.json); do serena get_symbols_overview --file "$file" # Context grepai trace callers "$(jq -r '.[].name' /tmp/async.json)" # UsagedoneRule: Complex tasks need multiple perspectives.
Pitfall 5: Over-Engineering Simple Searches
Section titled “Pitfall 5: Over-Engineering Simple Searches”❌ Wrong:
# Setup grepai + Ollama just to find a TODO commentgrepai search "TODO comments in the code"✅ Right:
rg "TODO" --type tsRule: Use the simplest tool that works.
Tool Selection Cheatsheet
Section titled “Tool Selection Cheatsheet”Quick Decision Matrix
Section titled “Quick Decision Matrix”| Your Situation | Use This | Not This |
|---|---|---|
”Find function login” | rg “login” | grepai search “login" |
| "Find login-related code” | grepai “login flow” | rg “login.*" |
| "Rename function safely” | Serena find_symbol | rg + sed |
| ”Who calls this function?“ | grepai trace callers | rg + grep |
| ”Get file structure” | Serena overview | rg “class|function" |
| "Find async without try/catch” | ast-grep | rg “async.*{" |
| "Migrate React classes” | ast-grep | rg + manual |
| ”Find TODOs” | rg “TODO” | Any other tool |
Setup Priority
Section titled “Setup Priority”Recommended Setup Order:
- Start: rg (already built-in with Grep tool) ✅
- Next: Serena MCP (symbol awareness, session memory)
- Then: grepai (semantic search + call graph)
- Finally: ast-grep (structural patterns, large refactoring)
Rationale: 90% of searches work with rg + Serena. Add grepai for semantic needs. Only add ast-grep if doing large-scale refactoring/migration.
Summary: The 4-Tool Symphony
Section titled “Summary: The 4-Tool Symphony”┌─────────────────────────────────────────────────────────┐│ SEARCH TOOL MASTERY │├─────────────────────────────────────────────────────────┤│ ││ rg (ripgrep) → Fast, exact text matching ││ ├─ Use: 90% of searches ││ └─ Speed: ⚡ ~20ms ││ ││ grepai → Semantic + Call graph ││ ├─ Use: Concept discovery, dependency tracing ││ └─ Speed: 🐢 ~500ms (but finds what rg can't) ││ ││ Serena → Symbol-aware + Session memory ││ ├─ Use: Refactoring, structure understanding ││ └─ Speed: ⚡ ~100ms ││ ││ ast-grep → AST structural patterns ││ ├─ Use: Large migrations, complex patterns ││ └─ Speed: 🕐 ~200ms ││ ││ ═══════════════════════════════════════════════════ ││ ││ Master the combination, not individual tools. ││ Each tool has a sweet spot — use the right one. ││ │└─────────────────────────────────────────────────────────┘Further Reading
Section titled “Further Reading”Last updated: January 2026 Compatible with: Claude Code 2.1.7+