/lessons/2026-04-03
ripgrep's Hidden Power: Advanced Search Configuration
Beyond basic searching, ripgrep's configuration system, preprocessing filters, and specialized flags transform it from fast grep into a surgical code analysis engine.
ripgrep's Hidden Power: Advanced Search Configuration
Most developers know ripgrep as "the fast grep replacement." Nearly every AI coding agent that needs to search a codebase reaches for the same binary: ripgrep. When milliseconds matter - and they absolutely matter when an LLM is waiting for context - the difference between grep and ripgrep is the difference between a responsive agent and one that feels broken. But the real story isn't just speed—it's surgical precision through advanced configuration.
Claude Code (Anthropic's CLI agent) uses ripgrep as one of its primary tools for understanding codebases. When you ask Claude Code to fix a bug or add a feature, it runs rg commands to find relevant code, trace dependencies, and understand call patterns. Claude Code often runs 10-30 ripgrep searches in a single task, finding function definitions, usages, imports, test files, and configuration. This isn't luck—it's configuration mastery.
Configuration Files: Your Search Profile
ripgrep supports configuration files. Set RIPGREP_CONFIG_PATH to a configuration file. The file can specify one shell argument per line. Lines starting with # are ignored.
Create ~/.ripgreprc and point to it:
export RIPGREP_CONFIG_PATH="$HOME/.ripgreprc"
Your config becomes your search personality:
# Smart case by default
--smart-case
# Always show line numbers
--line-number
# Add context around matches
--context=2
# Ignore these patterns globally
--glob=!*.log
--glob=!node_modules/**
--glob=!.git/**
--glob=!dist/**
--glob=!build/**
# Custom file types
--type-add=proto:*.proto
--type-add=config:*.{yml,yaml,toml,json,ini}
--type-add=docs:*.{md,rst,txt,adoc}
# Performance tweaks
--mmap
Now rg pattern runs with your entire profile applied. No more memorizing flags.
Preprocessing Filters: Search Beyond Text
This includes, but is not limited to, configuration files, passthru, support for searching compressed files, multiline search and opt-in fancy regex support via PCRE2. The --pre flag transforms any file type before searching:
# Search inside compressed files
rg --pre 'zcat' 'error' logs/
# Search PDF content
rg --pre 'pdftotext {} -' 'contract' documents/
# Search Docker images as tar streams
rg --pre 'docker save {} | tar -xO' 'FROM ubuntu' .
# Search minified JS after beautification
rg --pre 'js-beautify' 'function.*login' assets/
The preprocessing happens transparently. ripgrep streams the transformed content without touching your original files.
Type System Mastery
ripgrep can search specific types of files. For example, rg -tpy foo limits your search to Python files and rg -Tjs foo excludes JavaScript files from your search. ripgrep can be taught about new file types with custom matching rules.
Define project-specific types:
# Infrastructure files
rg --type-add 'infra:*.{tf,tfvars,hcl}' --type infra 'resource.*aws_instance'
# Frontend assets
rg --type-add 'assets:*.{scss,less,styl,vue,svelte}' --type assets '@import'
# Config files that might contain secrets
rg --type-add 'secrets:*.{env,properties,conf,ini}' --type secrets 'password|key|token'
# Multiple extensions, multiple patterns
rg --type-add 'backend:*.{go,rs,py,rb,php}' --type backend 'func.*Handler|def.*handler|function.*handle'
Search specific file types or define your own. Useful when: Built-in file type matching isn't enough. The type system composes—combine multiple types, exclude unwanted ones, or build complex inclusion patterns.
Context Control for Code Analysis
Show lines after, before, or around a match. Useful when: You want surrounding context, not just isolated matching lines. Makes your search results feel story-like instead of fragmented.
# Function signatures with their bodies
rg --after-context=10 'func.*Handler'
# Import statements and what follows
rg --before-context=2 --after-context=5 '^import'
# Error handling patterns with context
rg --context=3 'panic\!|unwrap\(\)' --type rust
# API endpoint definitions with middleware
rg --context=8 'app\.(get|post|put|delete)' --type js
Context isn't just pretty output—it's essential for understanding code relationships without opening files.
JSON Output for Tool Integration
Output matches in JSON lines format. Useful when: You want machine-readable results (for piping into scripts, or UIs). VS Code search runs a variation of this to parse results live.
# Pipe to jq for processing
rg --json 'TODO' | jq -r 'select(.type=="match") | "\(.data.path.text):\(.data.line_number): \(.data.lines.text)"'
# Count matches per file type
rg --json --type-all 'function' | jq -r 'select(.type=="match") | .data.path.text' | grep -o '\.[^.]*$' | sort | uniq -c
# Extract function names with metadata
rg --json --only-matching 'function\s+\w+' --type js | jq -r '.data | "\(.path.text):\(.line_number): \(.lines.text)"'
JSON mode transforms ripgrep into a structured data extraction engine.
Pro Tip
Shell completions (and man page) can be created via rg --generate. Generate completions for your shell:
# Bash
rg --generate complete-bash > ~/.local/share/bash-completion/completions/rg
# Zsh
rg --generate complete-zsh > ~/.zfunc/_rg
# Fish
rg --generate complete-fish > ~/.config/fish/completions/rg.fish
# PowerShell
rg --generate complete-powershell > rg.ps1
With completions installed, shell tab-completion works for all ripgrep flags, file types, and glob patterns.
Example: Multi-Stage Security Audit
#!/bin/bash
# security-audit.sh - Comprehensive codebase security scan
# 1. Find potential secrets
echo "=== Potential Secrets ==="
rg --type-add 'secrets:*.{env,properties,yaml,json,py,js,go,rs}' \
--type secrets \
--ignore-case \
'password|secret|key|token|api_key' \
--context=1 \
--json | jq -r 'select(.type=="match") | "\(.data.path.text):\(.data.line_number)"'
# 2. Check for hardcoded credentials patterns
echo "=== Hardcoded Credentials ==="
rg --type-add 'code:*.{py,js,go,rs,java,php,rb}' \
--type code \
--pcre2 \
'(?i)(password|secret|key)\s*[=:]\s*["\'][^"\'
]{8,}["\']' \
--only-matching \
--line-number
# 3. Find SQL injection risks
echo "=== SQL Injection Risks ==="
rg --type-add 'web:*.{py,js,php,rb,java}' \
--type web \
--multiline \
--pcre2 \
'(?s)(query|execute).*\+.*\$\{|\$[a-zA-Z]' \
--context=2
# 4. Look for debug/development code
echo "=== Debug Code ==="
rg --type-add 'all-code:*.{py,js,go,rs,java,php,rb,cpp,c}' \
--type all-code \
'console\.log|print\(|debug|TODO.*SECURITY|FIXME.*AUTH' \
--line-number
This script demonstrates ripgrep's power as a security analysis engine—not just a search tool, but a configurable code inspection platform. The combination of custom types, preprocessing, regex engines, and output formats transforms simple text search into sophisticated codebase analysis.