--- title: "Search Tools Mastery: Combining rg, grepai, Serena & ast-grep" description: "Master code search by combining the right tools for maximum efficiency" tags: [workflow, search, guide, mcp] --- # 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 1. [Quick Reference Matrix](#quick-reference-matrix) 2. [Tool Comparison](#tool-comparison) 3. [Decision Tree](#decision-tree) 4. [Combined Workflows](#combined-workflows) 5. [Real-World Scenarios](#real-world-scenarios) 6. [Performance Optimization](#performance-optimization) 7. [Common Pitfalls](#common-pitfalls) --- ## 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 ### 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 | 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 ### 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 2 ``` ### 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 ``` 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 pattern ``` --- ## Combined Workflows ### Workflow 1: Exploring Unknown Codebase **Goal**: Understand a new project quickly **Step-by-step**: ```bash # 1. SEMANTIC DISCOVERY (grepai) # Find files related to authentication grepai search "user authentication and session management" # β†’ Output: auth.service.ts, session.middleware.ts, user.controller.ts # 2. STRUCTURAL OVERVIEW (Serena) # Understand each file's structure serena 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 used grepai trace callers "login" # β†’ Output: Called by UserController, ApiGateway, AdminPanel # 4. EXACT SEARCH (rg) # Find specific implementation details rg "validateSession" --type ts -A 5 # β†’ Output: Full function with 5 lines of context ``` **Result**: Complete understanding in 4 commands (vs 30+ file reads) --- ### Workflow 2: Large-Scale Refactoring **Goal**: Rename `createSession` β†’ `initializeUserSession` across 50+ files **Step-by-step**: ```bash # 1. IMPACT ANALYSIS (grepai trace) # Understand full scope grepai trace callers "createSession" # β†’ Output: 47 callers across 23 files grepai trace callees "createSession" # β†’ Output: Calls validateUser, createToken, storeSession # 2. STRUCTURAL VALIDATION (ast-grep) # Ensure consistent usage pattern ast-grep "createSession($$$ARGS)" # β†’ Output: All invocations with their argument patterns # 3. SYMBOL-AWARE REFACTORING (Serena) # Precise renaming serena 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 remain rg "createSession" --type ts # β†’ Should return 0 results ``` **Result**: Safe refactoring with full dependency awareness --- ### Workflow 3: Security Audit **Goal**: Find security vulnerabilities **Step-by-step**: ```bash # 1. SEMANTIC DISCOVERY (grepai) # Find security-sensitive code grepai search "SQL query construction" grepai search "user input validation" grepai search "password handling" # 2. STRUCTURAL PATTERNS (ast-grep) # Find specific vulnerability patterns # SQL injection risks ast-grep 'db.query(`${$VAR}`)' # XSS risks ast-grep 'innerHTML = $VAR' # Missing error handling ast-grep -p 'async function $F($$$) { $$$BODY }' \ --without 'try { $$$TRY } catch' # 3. DEPENDENCY TRACING (grepai) # See where vulnerable code is called grepai trace callers "executeQuery" # β†’ Identify all entry points # 4. EXACT VERIFICATION (rg) # Confirm findings rg "innerHTML\s*=" --type ts rg "password" --type ts | rg -v "hashed" ``` **Result**: Comprehensive security audit in minutes --- ## Real-World Benchmarks ### 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](https://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 **Goal**: Migrate React class components β†’ hooks **Step-by-step**: ```bash # 1. INVENTORY (ast-grep) # Find all class components ast-grep 'class $C extends React.Component' # β†’ Output: 34 components to migrate # 2. DEPENDENCY ANALYSIS (grepai) # Understand component relationships for 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 used ast-grep 'componentDidMount() { $$$BODY }' ast-grep 'componentWillReceiveProps($$$) { $$$BODY }' # β†’ Map to equivalent hooks # 4. INCREMENTAL MIGRATION (Serena + ast-grep) # Migrate one component at a time serena find_symbol --name "UserProfile" --include-body true # β†’ Get full component code # Use ast-grep to transform ast-grep --rewrite \ --from 'class $C extends React.Component' \ --to 'const $C = () => { }' # 5. VERIFICATION (rg + grepai) # Ensure migration successful rg "React.Component" --type tsx # Should decrease grepai search "component lifecycle methods" # Find any missed ``` **Result**: Systematic migration with minimal breakage --- ### Workflow 5: Performance Optimization **Goal**: Identify and fix performance bottlenecks **Step-by-step**: ```bash # 1. HOTSPOT DISCOVERY (grepai) # Find performance-critical code grepai search "heavy computation or loops" grepai search "database queries in loops" # 2. PATTERN DETECTION (ast-grep) # Find N+1 query patterns ast-grep 'for ($$$) { await db.query($$$) }' # Find missing memoization ast-grep 'useMemo' --invert-match \ --in 'const $VAR = $$$' # 3. CALL GRAPH ANALYSIS (grepai trace) # Find hot paths grepai trace graph "renderUserList" --depth 3 # β†’ Visualize dependency tree # 4. SYMBOL TRACKING (Serena) # Track function changes serena write_memory "perf_baseline" \ "renderUserList: 450ms avg" # After optimization serena write_memory "perf_optimized" \ "renderUserList: 45ms avg (10x improvement)" # 5. VERIFICATION (rg) # Confirm optimizations applied rg "useMemo|useCallback" --type tsx ``` **Result**: Data-driven performance improvements --- ## Real-World Scenarios ### Scenario 1: "I Don't Know What I'm Looking For" **Problem**: New project, no documentation, need to add feature **Solution**: Semantic-first discovery ```bash # Start broad with meaning grepai search "user profile management" # β†’ Discover relevant files # Then narrow with structure serena get_symbols_overview --file user-profile.service.ts # β†’ Understand available functions # Finally, exact search for details rg "updateProfile" --type ts -C 3 ``` --- ### Scenario 2: "This Function is Called from Everywhere" **Problem**: Need to modify a function but worried about breaking things **Solution**: Dependency mapping first ```bash # 1. See all callers grepai trace callers "calculateTotal" # β†’ 47 callers found # 2. Analyze caller contexts for file in $(grepai trace callers "calculateTotal" --json | jq -r '.[].file'); do serena get_symbols_overview --file "$file" done # 3. Identify safe vs risky call sites ast-grep 'calculateTotal($ARGS)' --json # β†’ Group by argument patterns # 4. Make change with confidence # Now you know all impact points ``` --- ### Scenario 3: "Find All Code Doing X" **Problem**: Need to apply consistent pattern across codebase **Solution**: Combine semantic + structural ```bash # Example: Find all error handling code # 1. Semantic discovery grepai search "error handling and exception management" # 2. Structural patterns ast-grep 'try { $$$TRY } catch ($ERR) { $$$CATCH }' ast-grep 'throw new Error($MSG)' # 3. Verify consistency rg "catch\s*\(" --type ts | wc -l # Compare with ast-grep count to find anomalies ``` --- ### Scenario 4: "I Need to Understand This Module" **Problem**: Complex module with unclear responsibilities **Solution**: Multi-tool analysis ```bash # 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.ts ast-grep 'async $METHOD($$$)' --file payment.module.ts # 4. Read specific implementations (rg) rg "processPayment" --type ts -A 20 ``` --- ## Performance Optimization ### Choosing the Fastest Tool **General Rules**: 1. **Known exact text** β†’ Always use rg first 2. **Unknown exact text** β†’ Use grepai, then rg for verification 3. **Refactoring** β†’ Serena for symbol safety 4. **Large migrations** β†’ ast-grep for structural precision ### 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 **For large codebases (>100k lines)**: ```bash # Run searches in parallel # Terminal 1: Semantic discovery grepai search "authentication flow" > /tmp/grepai-results.json & # Terminal 2: Symbol indexing serena get_symbols_overview --file src/**/*.ts > /tmp/symbols.json & # Terminal 3: Pattern detection ast-grep 'async function $F' --json > /tmp/ast-results.json & # Wait for all, then combine results wait jq -s '.[0] + .[1] + .[2]' \ /tmp/grepai-results.json \ /tmp/symbols.json \ /tmp/ast-results.json ``` --- ## Common Pitfalls ### Pitfall 1: Using Semantic Search for Exact Matches ❌ **Wrong**: ```bash grepai search "createSession" # Slow, overkill ``` βœ… **Right**: ```bash rg "createSession" --type ts # Fast, precise ``` **Rule**: If you know the exact text, never use semantic search. --- ### Pitfall 2: Using rg for Conceptual Search ❌ **Wrong**: ```bash rg "auth.*login.*session" --type ts # Misses variations ``` βœ… **Right**: ```bash grepai search "authentication and session management" ``` **Rule**: Regex doesn't understand meaning, use semantic tools. --- ### Pitfall 3: Ignoring Call Graph Before Refactoring ❌ **Wrong**: ```bash # Directly refactor without checking callers rg "oldFunction" --type ts | sed 's/oldFunction/newFunction/g' ``` βœ… **Right**: ```bash # Check impact first grepai trace callers "oldFunction" # See 47 callers across 23 files # Then plan refactoring strategy ``` **Rule**: Always trace dependencies before modifying shared code. --- ### Pitfall 4: Not Combining Tools ❌ **Wrong**: ```bash # Use only one tool for complex task ast-grep 'async function $F' --json | jq '.[].file' | xargs -I {} vim {} # Blindly edit without understanding context ``` βœ… **Right**: ```bash # Combine for full understanding ast-grep 'async function $F' --json > /tmp/async.json for 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)" # Usage done ``` **Rule**: Complex tasks need multiple perspectives. --- ### Pitfall 5: Over-Engineering Simple Searches ❌ **Wrong**: ```bash # Setup grepai + Ollama just to find a TODO comment grepai search "TODO comments in the code" ``` βœ… **Right**: ```bash rg "TODO" --type ts ``` **Rule**: Use the simplest tool that works. --- ## Tool Selection Cheatsheet ### 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 **Recommended Setup Order**: 1. **Start**: rg (already built-in with Grep tool) βœ… 2. **Next**: Serena MCP (symbol awareness, session memory) 3. **Then**: grepai (semantic search + call graph) 4. **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 ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 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 - [Serena MCP Guide](../ultimate-guide.md#serena-semantic-code-analysis) - [grepai Documentation](../ultimate-guide.md#grepai-recommended-semantic-search) - [ast-grep Patterns Skill](../../examples/skills/ast-grep-patterns.md) - [Architecture: Grep vs RAG History](../architecture.md#search-strategy-evolution) --- **Last updated**: January 2026 **Compatible with**: Claude Code 2.1.7+