Skip to content

Contributing

Reflex is written in Rust. This guide covers everything you need to contribute.

  • Rust 1.75+ (edition 2024)
  • Git
Terminal window
git clone https://github.com/reflex-search/reflex.git
cd reflex
cargo build --release
cargo test
Terminal window
RUST_LOG=debug cargo run -- query "pattern"
# Module-specific logging
RUST_LOG=reflex::query=debug cargo run -- query "pattern"
Terminal window
cargo doc --open
src/
├── main.rs # CLI entry point
├── cache.rs # Cache manager (.reflex/ directory)
├── indexer.rs # Trigram indexer
├── trigram.rs # Trigram extraction and index
├── content_store.rs # Binary content storage
├── query.rs # Query engine
├── models.rs # Language enum, shared types
├── parsers/
│ ├── mod.rs # Parser factory
│ ├── rust.rs # Rust parser
│ ├── typescript.rs # TypeScript parser
│ ├── javascript.rs # JavaScript parser
│ ├── python.rs # Python parser
│ ├── go.rs # Go parser
│ ├── java.rs # Java parser
│ ├── c.rs # C parser
│ ├── cpp.rs # C++ parser
│ ├── csharp.rs # C# parser
│ ├── php.rs # PHP parser
│ ├── ruby.rs # Ruby parser
│ ├── kotlin.rs # Kotlin parser
│ ├── vue.rs # Vue parser
│ ├── svelte.rs # Svelte parser
│ └── zig.rs # Zig parser
└── ...
tests/
├── integration_test.rs # End-to-end tests
└── performance_test.rs # Latency benchmarks
  • Standard Rust conventions: rustfmt + clippy
  • Modules: snake_case
  • Structs/enums: PascalCase
  • Functions: snake_case
  • Constants: SCREAMING_SNAKE_CASE
  • Error handling: anyhow::Result, anyhow::bail!(), .context()
  • Public APIs must have rustdoc documentation
Terminal window
cargo fmt --check
cargo clippy -- -D warnings

Embedded in source files as #[cfg(test)] modules:

Terminal window
cargo test --lib

End-to-end workflows in tests/:

Terminal window
cargo test --test integration_test

Latency benchmarks (run in release mode):

Terminal window
cargo test --test performance_test --release
  • New features must include tests
  • Language parsers need 8–15 tests each
  • Target >80% coverage on critical paths

Reflex uses Conventional Commits:

<type>(<scope>): <description>
[optional body]
[optional footer(s)]

Types: feat, fix, docs, refactor, perf, test, chore

Breaking changes use a BREAKING CHANGE: footer or ! after the type.

  • Tests pass (cargo test)
  • Code formatted (cargo fmt --check)
  • No clippy warnings (cargo clippy -- -D warnings)
  • Documentation updated if public API changed
  • Commit messages follow conventional format
  • PR description explains the change
  1. Add the Tree-sitter grammar to Cargo.toml
  2. Update the Language enum in src/models.rs with the new variant
  3. Create a parser at src/parsers/your_language.rs implementing symbol extraction
  4. Register the parser in the factory at src/parsers/mod.rs
  5. Add file extensions in src/indexer.rs
  6. Write tests — 8–15 tests covering all symbol types
  7. Update documentation — README, this website, and API docs
Terminal window
# Check database schema
sqlite3 .reflex/meta.db ".schema"
# View file list
sqlite3 .reflex/meta.db "SELECT * FROM files LIMIT 10;"
# Check index statistics
sqlite3 .reflex/meta.db "SELECT * FROM statistics;"
Terminal window
hexdump -C .reflex/trigrams.bin | head
hexdump -C .reflex/content.bin | head

Releases are automated via release-plz. Pushing to main triggers a version bump, CHANGELOG update, and release PR.

Three guiding values:

  1. Speed — sub-100ms queries are non-negotiable
  2. Accuracy — deterministic, complete results
  3. Simplicity — do fewer things well