Reflex
Local-first code search engine with full-text search, symbol extraction, and dependency analysis for AI coding workflows
Reflex is a code search engine designed for developers and AI coding assistants. It combines trigram indexing for full-text search with Tree-sitter parsing for symbol extraction and static analysis for dependency tracking. Unlike symbol-only tools, Reflex finds every occurrence of patterns, function calls, variable usage, comments, and more with deterministic, repeatable results.
โจ Features
- ๐ Complete Coverage: Find every occurrence, not just symbol definitions
- โก Fast Queries: Trigram indexing with memory-mapped I/O for efficient search
- ๐ฏ Symbol-Aware: Runtime tree-sitter parsing for precise symbol filtering
- ๐ฅ๏ธ Interactive Mode: Live TUI for exploring code with instant search and filters
- ๐ Incremental: Only reindexes changed files (blake3 hashing)
- ๐ Multi-Language: Rust, TypeScript/JavaScript, Vue, Svelte, PHP, Python, Go, Java, C, C++, C#, Ruby, Kotlin, Zig
- ๐ค AI Query Assistant: Natural language search with
rfx ask(OpenAI, Anthropic, OpenRouter) - ๐ก MCP Support: Model Context Protocol server for AI assistants
- ๐ฆ Local-First: Fully offline, all data stays on your machine
- ๐จ Regex Support: Trigram-optimized regex search
- ๐ณ AST Queries: Structure-aware search with Tree-sitter
- ๐ Deterministic: Same query โ same results (no probabilistic ranking)
- ๐ Pulse: Auto-generated digest, wiki, and architecture map from structural index data
๐ Quick Start
Installation
# Via NPM
# Or via cargo
Important Setup Notes:
- Run
rfxcommands from the root of your project directory - Add
.reflex/to your.gitignorefile to exclude the search index from version control
Basic Usage
# Index your codebase
# Full-text search (finds all occurrences)
# Symbol-only search (definitions only)
# Filter by language and symbol kind
# Include dependency information (imports)
# Regex search
# Paths-only mode (for piping to other tools)
# Export as JSON for AI agents
๐ค AI Query Assistant
Don't want to remember search syntax? Use rfx ask to translate natural language questions into rfx query commands.
Setup
First-time setup requires configuring an AI provider (OpenAI, Anthropic, or OpenRouter). This configuration is shared by rfx ask and rfx pulse.
# Interactive configuration wizard (recommended)
# Check current configuration
This will guide you through:
- Selecting an AI provider
- Entering your API key
- Choosing a model (optional)
Configuration is saved to ~/.reflex/config.toml:
[]
= "openai" # or anthropic, openrouter
[]
= "sk-..."
= "gpt-4o-mini" # optional
Usage
There are two ways to use rfx ask:
- Interactive mode
Interactive chat mode with conversation history. This mode uses --agentic and --answer under the hood.
- CLI-only mode
One-shot, non-conversational commands that return results directly via CLI.
# Ask a question (generates and executes rfx query commands, only returns query results)
# Use a specific provider
# Agentic mode (multi-step reasoning with automatic context gathering)
# Get a conversational answer based on search results
How it works:
- Your natural language question is sent to an LLM
- The LLM generates one or more
rfx querycommands - You review and confirm (or use
--executeto auto-run) - Results are displayed as normal search output
Agentic mode (--agentic) enables multi-step reasoning where the LLM can:
- Gather context by running multiple searches
- Refine queries based on initial results
- Iteratively explore the codebase
- Generate comprehensive answers with
--answer
๐ Command Reference
rfx index
Build or update the search index.
)
)
)
rfx query
Search the codebase with CLI or interactive TUI mode.
Interactive Mode (TUI):
# Launch interactive mode (no pattern required)
# Features:
# - Live search with instant results
# - Toggle filters: symbols-only, regex, language
# - Navigate results with keyboard (j/k, arrows)
# - Open files in $EDITOR (press 'o')
# - Query history with Ctrl+P/Ctrl+N
# - Press '?' for help, 'q' to quit
CLI Mode:
Run rfx query --help for full options.
Key Options:
--symbols, -s- Symbol-only search (definitions, not usage)--regex, -r- Treat pattern as regex--lang <LANG>- Filter by language--kind <KIND>- Filter by symbol kind (function, class, struct, etc.)--dependencies- Include dependency information (supports: Rust, TypeScript, JavaScript, Python, Go, Java, C, C++, C#, PHP, Ruby, Kotlin)--paths, -p- Return only file paths (no content)--json- Output as JSON--limit <N>- Limit number of results--timeout <SECS>- Query timeout (default: 30s)
Examples:
# Find function definitions named "parse"
# Find test functions using regex
# Search Rust files only
# Get paths of files with TODOs
# Include import information
rfx mcp
Start as an MCP (Model Context Protocol) server for AI coding assistants.
Error Handling:
If any MCP tool returns an error about a missing or stale index (e.g., "Index not found. Run 'rfx index' to build the cache first."), the AI agent should:
- Call
index_projectto rebuild the index - Wait for indexing to complete
- Retry the previously failed operation
This pattern ensures that queries always run against an up-to-date index.
Available MCP Tools:
list_locations- Fast location discovery (file + line only, minimal tokens)count_occurrences- Quick statistics (total count + file count)search_code- Full-text or symbol search with detailed resultssearch_regex- Regex pattern matchingsearch_ast- AST pattern matching (structure-aware, slow)index_project- Trigger reindexingget_dependencies- Get all dependencies of a specific fileget_dependents- Get all files that depend on a file (reverse lookup)get_transitive_deps- Get transitive dependencies up to a specified depthfind_hotspots- Find most-imported files (with pagination)find_circular- Detect circular dependencies (with pagination)find_unused- Find files with no incoming dependencies (with pagination)find_islands- Find disconnected components (with pagination)analyze_summary- Get dependency analysis summary (counts only)
rfx analyze
Analyze codebase structure and dependencies. By default shows a summary; use specific flags for detailed results.
Subcommands:
--circular- Detect circular dependencies (A โ B โ C โ A)--hotspots- Find most-imported files--unused- Find files with no incoming dependencies--islands- Find disconnected components
Pagination (default: 200 results per page):
- Use
--limit Nto specify results per page - Use
--offset Nto skip first N results - Use
--allto return unlimited results
Examples:
# Show summary of all analyses
# Find circular dependencies
# Find hotspots (most-imported files)
# Find unused files
# Find disconnected components (islands)
# Get JSON summary of all analyses
# Get pretty-printed JSON summary
# Paginate results
# Export as JSON with pagination metadata
JSON Output Format (specific analyses with pagination):
Summary JSON Output Format (bare rfx analyze --json):
rfx deps
Analyze dependencies for a specific file. Shows what a file imports (dependencies) or what imports it (dependents).
Key Options:
--reverse- Show files that depend on this file (reverse lookup)--depth N- Traverse N levels deep for transitive dependencies (default: 1)--format- Output format: tree, table, json (default: tree)--json- Output as JSON--pretty- Pretty-print JSON output
Examples:
# Show direct dependencies
# Show files that import this file (reverse lookup)
# Show transitive dependencies (depth 3)
# JSON output
# Pretty-printed JSON
# Table format
Supported Languages: Rust, TypeScript, JavaScript, Python, Go, Java, C, C++, C#, PHP, Ruby, Kotlin
Note: Only static imports (string literals) are tracked. Dynamic imports are filtered by design.
rfx context
Generate codebase context for AI prompts. Useful with rfx ask --additional-context.
Key Options:
--structure- Show directory structure--file-types- Show file type distribution--project-type- Detect project type (CLI/library/webapp/monorepo)--framework- Detect frameworks and conventions--entry-points- Show entry point files--test-layout- Show test organization pattern--config-files- List important configuration files--path <PATH>- Focus on specific directory--depth <N>- Tree depth for structure (default: 1)
By default (no flags), all context types are shown. Use individual flags to show specific types only.
Examples:
# Full context (all types - default behavior)
# Full context for monorepo subdirectory
# Specific context types only
# Use with semantic queries
rfx llm
Manage LLM provider configuration. This is the central place to set up API keys and model preferences used by both rfx ask and rfx pulse.
Example output of rfx llm status:
Provider: openrouter
Model: meta-llama/llama-4-maverick
API key: configured (sk-or-...****)
Configuration is stored in ~/.reflex/config.toml and applies to all LLM-powered features.
rfx pulse
Generate codebase intelligence surfaces from structural index data. Pulse turns the facts Reflex already extracts (symbols, dependencies, hotspots, file metrics) into browsable documentation.
Surfaces:
- Digest - A periodic change report comparing two snapshots, showing file changes, dependency shifts, hotspot movements, and threshold alerts
- Wiki - Per-module documentation pages with structure breakdowns, dependency lists, metrics, and optional LLM-generated summaries
- Map - An architecture diagram exported as Mermaid or D2
- Site - A complete static HTML site combining all three surfaces
LLM narration is optional. When an API key is configured (via rfx llm config), Pulse uses your LLM provider to generate concise narrative summaries for each section. Without an API key, all output is structural-only. Use --no-llm to explicitly skip narration even when a key is available.
LLM responses are cached in .reflex/pulse/llm-cache/ keyed by structural content hash, so repeated runs with the same data skip the LLM entirely.
Prerequisites: Run rfx index and rfx snapshot before using Pulse. Digests compare two snapshots, so you need at least one snapshot (two for a diff).
# Generate a structural-only digest (no LLM required)
# Generate a digest with LLM narration (requires configured API key)
# Compare specific snapshots
# Output as JSON
# Generate wiki pages for all detected modules
# Generate wiki with LLM summaries
# Write wiki pages to a directory as markdown files
# Output as JSON
# Export architecture map (Mermaid format, default)
# Export as D2 format
# Focus on a specific module
# Write to file
# Generate a complete static HTML site with all surfaces
# Structural-only site (no LLM)
# Select specific surfaces
# Clean output directory before generating
# Custom title and base URL
Other Commands
rfx stats- Display index statisticsrfx clear- Clear the search indexrfx list-files- List all indexed filesrfx watch- Watch for file changes and auto-reindex
Run rfx <command> --help for detailed options.
๐ณ AST Pattern Matching
Reflex supports structure-aware code search using Tree-sitter AST queries.
โ ๏ธ WARNING: AST queries are SLOW and scan the entire codebase. Use --symbols instead for 95% of cases (much faster).
When to use AST queries:
- You need to match code structure, not just text
--symbolssearch is insufficient for your use case- You have a very specific structural pattern
Basic usage:
# Example: Find all Rust functions
# Example: Find all TypeScript classes
Supported languages: Rust, TypeScript, JavaScript, Python, Go, Java, C, C++, C#, PHP, Ruby, Kotlin, Zig
For detailed AST query syntax and examples, see the Tree-sitter documentation.
๐ Supported Languages/Dialects
| Language | Extensions | Symbol Extraction |
|---|---|---|
| Rust | .rs |
Functions, structs, enums, traits, impls, modules, methods |
| TypeScript | .ts, .tsx, .mts, .cts |
Functions, classes, interfaces, types, enums, React components |
| JavaScript | .js, .jsx, .mjs, .cjs |
Functions, classes, constants, methods, React components |
| Vue | .vue |
Functions, constants, methods from <script> blocks |
| Svelte | .svelte |
Functions, variables, reactive declarations |
| PHP | .php |
Functions, classes, interfaces, traits, methods, namespaces, enums |
| Python | .py |
Functions, classes, methods, decorators, lambdas |
| Go | .go |
Functions, types, interfaces, methods, constants |
| Java | .java |
Classes, interfaces, enums, methods, fields, constructors |
| C | .c, .h |
Functions, structs, enums, unions, typedefs |
| C++ | .cpp, .hpp, .cxx |
Functions, classes, namespaces, templates, methods |
| C# | .cs |
Classes, interfaces, structs, enums, methods, properties |
| Ruby | .rb, .rake, .gemspec |
Classes, modules, methods, constants, variables |
| Kotlin | .kt, .kts |
Classes, functions, interfaces, objects, properties |
| Zig | .zig |
Functions, structs, enums, constants, variables |
Note: Full-text search works on all file types regardless of parser support. Symbol filtering requires a language parser.
๐๏ธ Architecture
Reflex uses a trigram-based inverted index combined with runtime symbol detection:
Indexing Phase
- Extract trigrams (3-character substrings) from all files
- Build inverted index:
trigram โ [file_id, line_no] - Store full file contents in memory-mapped
content.bin - Start background symbol indexing (caches symbols for faster queries)
Query Phase
- Full-text queries: Intersect trigram posting lists โ verify matches
- Symbol queries: Trigrams narrow to ~10-100 candidates โ parse with tree-sitter โ filter symbols
- Memory-mapped I/O for instant cache access
Cache Structure (.reflex/)
.reflex/
meta.db # SQLite: file metadata, stats, config, hashes
trigrams.bin # Inverted index (memory-mapped)
content.bin # Full file contents (memory-mapped)
config.toml # Index settings
indexing.status # Background symbol indexer status
โก Performance
Reflex is designed for speed at every level:
Query Performance:
- Full-text & Regex: Efficient queries via trigram indexing
- Symbol queries: Slower due to runtime tree-sitter parsing, but still efficient
- Cached queries: Repeated searches benefit from memory-mapped cache
- Scales well from small projects to large codebases (10k+ files)
Indexing Performance:
- Initial indexing: Parallel processing using 80% of CPU cores
- Incremental updates: Only reindexes changed files via blake3 hashing
- Memory-mapped I/O: Zero-copy access for cache reads
๐ง Configuration
Reflex respects .gitignore files automatically. Additional configuration via .reflex/config.toml:
[]
= [] # Empty = all supported languages
= 10485760 # 10 MB
= false
[]
= 100
[]
= 0 # 0 = auto (80% of available cores)
๐ค AI Integration
Reflex provides clean JSON output for AI coding assistants and automation:
Output includes file paths, line numbers, symbol types, and code previews with pagination metadata.
๐ Use Cases
- Code Navigation: Find all usages of functions, classes, and variables
- Refactoring: Identify all call sites before making changes
- AI Assistants: Retrieve relevant code snippets and context for LLMs
- Debugging: Locate where variables and functions are used
- Documentation: Find examples of API usage across the codebase
- Security: Search for potential vulnerabilities or anti-patterns
๐งช Testing
Reflex has comprehensive test coverage including core modules, real-world code samples across all supported languages, and end-to-end workflows.
๐ค Contributing
Contributions welcome! Reflex is built to be:
- Fast: Efficient search using trigram indexing and memory-mapped I/O
- Accurate: Complete coverage with deterministic results
- Extensible: Easy to add new language parsers
๐ License
MIT License - see LICENSE for details.
๐ Acknowledgments
Built with:
- tree-sitter - Incremental parsing
- rkyv - Zero-copy deserialization
- memmap2 - Memory-mapped I/O
- rusqlite - SQLite bindings
- blake3 - Fast hashing
- ignore - gitignore support
Inspired by:
- Zoekt - Trigram-based code search
- Sourcegraph - Code search for teams
- ripgrep - Fast text search
Made with โค๏ธ for developers and AI coding assistants