Contributing to GraphLite
January 17, 2026 ยท View on GitHub
Thank you for your interest in contributing to GraphLite! We're excited to have you join our community. This guide will help you get started.
Table of Contents
- Code of Conduct
- AI-Assisted Development Philosophy
- Getting Started
- Development Setup
- How to Contribute
- Coding Standards
- Testing Requirements
- Submitting Changes
- Review Process
- Community
Code of Conduct
All contributors are expected to follow these standards:
- Treat everyone with respect - We're building this together
- Be constructive in feedback - Focus on improvements, not criticism
- Welcome newcomers - Help new contributors get started
- Collaborate openly - Share knowledge and help others learn
- Assume good intentions - Give others the benefit of the doubt
AI-Assisted Development Philosophy
GraphLite was built using modern AI-assisted development practices, leveraging Claude Code by Anthropic as a pair programming partner throughout the development process.
Our Philosophy
We believe in transparent, hybrid development where AI and humans work together:
- AI accelerates coding, testing, and documentation
- Humans provide architecture design, goals, direction, and validation
- Collaboration produces faster and better results
AI Use in Contributions
We believe in full transparency about AI involvement and welcome AI-assisted contributions.
If you use AI tools (Claude, Copilot, etc.) in your contributions:
Allowed:
- Using AI to write boilerplate code
- AI-generated tests and documentation
- AI assistance with debugging and optimization
- Using AI to learn and understand the codebase
Required:
- Human reviews all AI-generated code - You must understand what the code does
- Design documentation - Provide a concise, readable design doc explaining your approach
- Automated tests - Add comprehensive test suites
- Manual testing - Include a script of manual tests run along with results
- Take ownership - You are responsible for code quality and correctness
Not Allowed:
- Copy-pasting AI code without understanding
- Submitting code with "the AI said it works" as the only verification
- PRs without tests or documentation
- Code that violates architectural patterns specified in Critical Rules.
Transparency:
- You may mention AI tools used in PR descriptions (optional for small changes)
- Be transparent about AI use for significant contributions
- Your contributions will be licensed under Apache-2.0
- You retain copyright on your contributions
Remember: AI is a tool, not a replacement for engineering judgment. We value well-designed, thoroughly tested contributions over speed.
Getting Started
Prerequisites
Before you begin, ensure you have the following installed:
- Rust (1.70 or higher): Install via rustup
- Git: For version control
- Cargo: Comes with Rust installation
Optional for specific contributions:
- Python 3.8+: For Python binding development
- Java 11+: For Java binding development
- Docker: For integration testing
First-Time Contributors
If you're new to open source, welcome! Here are some good first steps:
- Read the documentation: Start with README.md and Quick Start
- Look for "good first issue" labels: These are beginner-friendly tasks
- Join our Discord: Get help from the community
- Start small: Documentation fixes, test improvements, small bug fixes
Development Setup
1. Fork and Clone
REQUIRED: All contributors must fork the repository and work on their fork. Do not request direct write access to the main repository.
# 1. Fork the repository on GitHub (click "Fork" button)
# 2. Clone YOUR fork (not the original repository)
git clone https://github.com/YOUR_USERNAME/GraphLite.git
cd GraphLite
# 3. Add upstream remote to sync with the original repository
git remote add upstream https://github.com/ORIGINAL_OWNER/GraphLite.git
This fork-based workflow ensures you can test all changes independently before submitting a Pull Request.
2. Build the Project
# Build all components
cargo build --all
# Run the CLI
cargo run --bin gql-cli
# Run tests to verify setup
cargo test --all
3. Install Development Tools
# Install pre-commit hooks to enforce code quality rules
bash scripts/install_hooks.sh
# Install formatting tools
rustup component add rustfmt clippy
# Optional: Install cargo-watch for auto-recompilation
cargo install cargo-watch
About Git Hooks:
The pre-commit hook automatically checks your code for rule violations before allowing commits. It validates:
- Rust code patterns (Rules #1-10)
- Documentation quality (Rule #11: No emojis in markdown)
To bypass the hook (use sparingly): git commit --no-verify
4. Verify Your Setup
# Run the full test suite
cargo test --all
# Check code formatting
cargo fmt -- --check
# Run linter
cargo clippy -- -D warnings
# Run examples
cd examples/rust/sdk/drug_discovery
cargo run
How to Contribute
Reporting Bugs
Before creating a bug report:
- Check existing issues: Someone might have already reported it
- Try latest version: The bug might already be fixed
- Minimal reproduction: Create the smallest example that shows the bug
Bug Report Template:
**Environment:**
- OS: [e.g., macOS 14.0, Ubuntu 22.04]
- Rust version: [run `rustc --version`]
- GraphLite version: [e.g., 0.1.0]
**Description:**
Clear description of the bug
**Steps to Reproduce:**
1. Step one
2. Step two
3. See error
**Expected Behavior:**
What you expected to happen
**Actual Behavior:**
What actually happened
**Code Sample:**
```rust
// Minimal code that reproduces the issue
Error Messages:
Paste any error messages or stack traces
Additional Context: Any other relevant information
### Suggesting Features
We love feature ideas! Before suggesting:
1. **Check the roadmap**: It might already be planned ([docs/ROADMAP.md](../docs/ROADMAP.md))
2. **Check existing feature requests**: Search open issues
3. **Consider scope**: Does it fit GraphLite's vision as an embedded graph DB?
**Feature Request Template:**
```markdown
**Problem Statement:**
What problem does this solve?
**Proposed Solution:**
How would you like this feature to work?
**Alternatives Considered:**
What other approaches did you consider?
**Use Case:**
Describe your specific use case
**Implementation Ideas:**
(Optional) Any thoughts on implementation?
**Breaking Changes:**
Would this require breaking changes?
Contributing Code
We accept pull requests for:
- Bug fixes: Always welcome!
- Documentation improvements: Documentation correction and more examples
- Test improvements: Better coverage, edge cases
- Performance optimizations: With benchmarks showing improvement
- New features: Discuss in an issue first (before coding)
Coding Standards
Rust Style Guide
GraphLite follows the Rust API Guidelines and standard Rust conventions:
Formatting
# Auto-format all code
cargo fmt --all
# Check formatting without modifying
cargo fmt --all -- --check
Linting
# Run Clippy linter on all targets (REQUIRED before each commit)
./scripts/clippy_all.sh --all
# Auto-fix suggestions where possible
./scripts/clippy_all.sh --fix
# Strict mode (treat warnings as errors)
./scripts/clippy_all.sh --all --strict
Pre-Commit Checklist
REQUIRED: Run these commands before EVERY commit:
# 1. Format code (auto-fix)
cargo fmt --all
# 2. Run clippy on all targets (must pass)
./scripts/clippy_all.sh --all
# 3. Verify formatting passes (optional - for peace of mind)
cargo fmt --all -- --check
Why this matters:
- Formatting issues will cause CI to fail
- Clippy errors will block your PR from merging
- Running these locally saves time and CI resources
Quick validation before push:
./scripts/validate_ci.sh --quick # Runs both checks above + more
Code Organization
- Modules: One file per module, clear separation of concerns
- Visibility: Use
pub(crate)for internal APIs,pubonly for public API - Error handling: Use
Result<T, Error>consistently, avoidunwrap()in library code - Documentation: All public items must have doc comments
Naming Conventions
// Module names: snake_case
mod query_executor;
// Type names: PascalCase
struct QueryCoordinator;
enum StatementType;
// Functions and variables: snake_case
fn process_query() {}
let session_id = "...";
// Constants: SCREAMING_SNAKE_CASE
const MAX_QUERY_SIZE: usize = 1024;
// Lifetimes: short, descriptive
fn parse<'a>(input: &'a str) -> Result<Node<'a>>;
Documentation Comments
/// Brief one-line description.
///
/// More detailed explanation if needed. Can include:
/// - Multiple paragraphs
/// - Examples
/// - Error conditions
///
/// # Examples
///
/// ```
/// use graphlite::QueryCoordinator;
///
/// let coordinator = QueryCoordinator::from_path("./mydb")?;
/// let session = coordinator.create_simple_session("user")?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// # Errors
///
/// Returns `Err` if:
/// - Database path is invalid
/// - Permissions are insufficient
///
/// # Panics
///
/// This function panics if called from within an async context.
pub fn process_query(&self, query: &str) -> Result<String> {
// Implementation
}
Critical Rules
GraphLite has specific architectural patterns enforced as rules to maintain code quality and consistency.
Rule Enforcement Tools
1. Manual Rule Check - Run anytime to check entire codebase:
bash scripts/check_code_patterns.sh
This script scans all Rust files and markdown files for rule violations across the entire project.
2. Automatic Pre-commit Hook - Install once to check on every commit:
bash scripts/install_hooks.sh
This installs a git pre-commit hook that validates only staged files before allowing commits. The hook will block commits that violate critical rules.
Key rules:
- ExecutionContext Management: Never create new
ExecutionContextinstances - Storage Manager Singleton: Never create new
StorageManagerinstances during query execution - Read vs Write Locks: Use read locks for read operations, write locks only for writes
- CatalogManager Singleton: Get from session context, don't create new instances
- Async Runtime Management: Don't create new Tokio runtimes repeatedly
- Helper Method Pattern: Access fields directly, not recursively
- Async Context Detection: Check if in async context before using
block_on() - Test Integrity: Fix bugs in code, not in tests (unless test is wrong)
- Session Manager Isolation: Use global SessionManager, don't create test-specific instances
- API Boundary: Use
QueryCoordinatoras the only public API - No Emojis in Documentation: All markdown files must be emoji-free for professional consistency
Before submitting a PR, verify your changes don't violate these rules.
Understanding Validation Scripts
GraphLite uses two different validation scripts with different purposes:
check_code_patterns.sh - GraphLite Architecture Validator
- Checks the 11 critical rules listed above
- GraphLite-specific patterns and anti-patterns
- Fast (~5 seconds)
- Run before committing code changes
validate_ci.sh - CI Pipeline Simulator
- Checks formatting, linting, build, tests
- Standard Rust tooling (cargo fmt, clippy, etc.)
- Slower (~30s quick, ~10min full)
- Run before pushing to GitHub
When to use each:
# Before committing (fast checks):
./scripts/check_code_patterns.sh # GraphLite rules
# Before pushing (comprehensive checks):
./scripts/validate_ci.sh --quick # CI simulation
See scripts/README.md for detailed comparison.
Testing Requirements
Test Coverage
All contributions must include tests:
- Bug fixes: Add test that reproduces the bug (should fail before fix, pass after)
- New features: Unit tests + integration tests
- Refactoring: Existing tests must pass
- Performance improvements: Include benchmarks
Running Tests
# Run all tests
cargo test --all
# Run specific test
cargo test test_name
# Run tests with output
cargo test -- --nocapture
# Run tests in specific module
cargo test --package graphlite --lib ast::tests
# Run integration tests only
cargo test --test '*'
# Run with logging
RUST_LOG=debug cargo test
Writing Tests
Unit Tests
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_query_parsing() {
let query = "MATCH (n) RETURN n";
let result = parse_query(query);
assert!(result.is_ok());
let statement = result.unwrap();
assert_eq!(statement.statement_type, StatementType::Query);
}
#[test]
fn test_invalid_query() {
let query = "INVALID SYNTAX";
let result = parse_query(query);
assert!(result.is_err());
}
}
Integration Tests
// In tests/integration_test.rs
use graphlite::QueryCoordinator;
use tempfile::TempDir;
#[test]
fn test_create_and_query_graph() {
let temp_dir = TempDir::new().unwrap();
let coordinator = QueryCoordinator::from_path(temp_dir.path()).unwrap();
let session = coordinator.create_simple_session("test_user").unwrap();
// Create schema
coordinator.process_query("CREATE SCHEMA /test", &session).unwrap();
coordinator.process_query("USE SCHEMA /test", &session).unwrap();
// Create graph and add data
coordinator.process_query("CREATE GRAPH test_graph", &session).unwrap();
coordinator.process_query(
"INSERT (:Person {name: 'Alice', age: 30})",
&session
).unwrap();
// Query data
let result = coordinator.process_query(
"MATCH (p:Person) RETURN p.name, p.age",
&session
).unwrap();
assert!(result.contains("Alice"));
assert!(result.contains("30"));
}
Test Isolation
Use the TestFixture pattern for integration tests:
use graphlite::test_utils::TestFixture;
#[test]
fn test_with_isolation() {
let fixture = TestFixture::new().unwrap();
// Each test gets unique schema/graph names
fixture.execute("INSERT (:Node {id: 1})").unwrap();
let result = fixture.query("MATCH (n) RETURN n").unwrap();
assert_eq!(result.len(), 1);
// Cleanup happens automatically when fixture drops
}
Submitting Changes
1. Create a Branch
# Update your fork
git fetch upstream
git checkout main
git merge upstream/main
# Create feature branch
git checkout -b feature/your-feature-name
# or for bug fixes
git checkout -b fix/issue-123
2. Make Your Changes
# Make changes, commit often
git add .
git commit -m "Add feature: brief description
More detailed explanation of what changed and why.
Fixes #123"
Commit Message Guidelines
Follow conventional commits format:
<type>(<scope>): <subject>
<body>
<footer>
Types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting)refactor: Code refactoringtest: Adding or updating testsperf: Performance improvementschore: Build process, tooling changes
Examples:
feat(parser): add support for OPTIONAL MATCH clause
Implements optional pattern matching according to ISO GQL spec.
Includes parser changes, executor logic, and comprehensive tests.
Closes #45
fix(executor): prevent stack overflow in recursive WITH clauses
Added depth tracking to prevent infinite recursion when WITH clauses
reference themselves. Added regression test.
Fixes #123
docs(readme): update installation instructions for Python bindings
Clarified Python version requirements and added troubleshooting section
for common installation issues.
3. Test Your Changes on Your Fork
IMPORTANT: All testing must be completed on your fork BEFORE submitting a Pull Request. Do not submit a PR with failing tests or untested code.
# Run full test suite (REQUIRED - must pass)
cargo test --all
# Check formatting (REQUIRED - must pass)
cargo fmt --all -- --check
# Run linter on all targets (REQUIRED - must pass)
./scripts/clippy_all.sh --all
# Run code pattern checks (REQUIRED - must pass)
./scripts/check_code_patterns.sh
# Run integration tests - parallel (RECOMMENDED - fast, ~75 seconds)
./scripts/run_integration_tests_parallel.sh --release --jobs=8
# OR run integration tests - sequential (slower, ~10-15 minutes)
./scripts/run_integration_tests.sh --release
# Validate CI will pass before pushing (RECOMMENDED)
./scripts/validate_ci.sh --quick # Fast check: formatting + linting
./scripts/validate_ci.sh --full # Complete check: includes build + tests
# Test examples still work (REQUIRED - verify manually)
cd examples/rust/sdk/drug_discovery
cargo run
All checks must pass on your fork before proceeding to create a PR.
4. Push and Create Pull Request
# Push to your fork
git push origin feature/your-feature-name
# Go to GitHub and create Pull Request from your fork
Pull Request Template
## Description
Brief description of what this PR does
## Motivation
Why is this change needed? What problem does it solve?
## Changes
- Change 1
- Change 2
- Change 3
## Testing
How was this tested?
- [ ] Unit tests added
- [ ] Integration tests added
- [ ] Manual testing performed
- [ ] Examples verified
**Testing Steps for Reviewers:**
Provide clear, step-by-step instructions for reviewers to test your changes:
1. Step-by-step instructions on how to build/run
2. Expected behavior at each step
3. How to verify the fix/feature works
4. Any specific test commands to run
## Checklist
- [ ] Code follows project style guidelines
- [ ] Tests pass locally (`cargo test --all`)
- [ ] Clippy linting passes (`./scripts/clippy_all.sh --all`)
- [ ] Code pattern checks pass (`./scripts/check_code_patterns.sh`)
- [ ] Documentation updated (if applicable)
- [ ] Documentation is concise and curated (no AI-generated fluff)
- [ ] CHANGELOG.md updated (for notable changes)
- [ ] Commit messages follow guidelines
- [ ] PR description is professional (no emojis, no copy-paste from AI tools)
- [ ] Clear testing steps provided for reviewers to verify the changes
## Related Issues
Closes #123
Related to #456
Review Process
What to Expect
- Initial Response: Within 72 hours (usually faster)
- Review Feedback: Maintainers may request changes
- CI Checks: All tests must pass
- Approval: At least one maintainer approval required
- Merge: Squash and merge into main branch
Review Criteria
Reviewers will check:
- Correctness: Does it work as intended?
- Tests: Adequate test coverage?
- Style: Follows coding standards?
- Documentation: Clear docs and comments?
- Architecture: Fits with existing design?
- Breaking Changes: Necessary and documented?
Responding to Feedback
Thanks for the review! I've made the following changes:
1. Fixed the lifetime issue in parse_query()
2. Added integration test for edge case
3. Regarding the async approach - could you clarify what you mean?
Latest commit: abc123
Recognition
We appreciate all contributors! Your contributions will be recognized:
- Contributors list: Added to README.md
- Release notes: Mentioned in CHANGELOG.md
- GitHub: Automatic contributor badge
- Social media: Shoutouts for significant contributions
Community
Communication Channels
- GitHub Issues: Bug reports, feature requests
- GitHub Discussions: Questions, ideas, general discussion
- Discord: Real-time chat with the community
- Twitter: @graphlite_db (announcements)
Getting Help
If you're stuck:
- Check documentation
- Search existing issues
- Ask in Discord
- Create a GitHub Discussion
Maintainers
Current maintainers:
- @yourusername (Lead maintainer)
Additional Resources
Contribution Ideas
Not sure where to start? Here are some ideas:
Documentation
- Fix typos or improve clarity
- Add more examples
- Write tutorials or blog posts
- Translate documentation
Testing
- Improve test coverage
- Add edge case tests
- Performance benchmarks
- Stress testing
Features (Discuss First!)
- ISO GQL compliance improvements
- Query optimization
- New aggregation functions
- Additional language bindings
Performance
- Query optimizer improvements
- Memory usage optimization
- Storage engine tuning
- Benchmark suite
Tooling
- IDE integrations
- CLI improvements
- Better error messages
- Developer tools
Thank You!
Your contributions make GraphLite better for everyone. We're grateful for your time and effort. Welcome to the community!
Questions? Feel free to ask in GitHub Discussions or Discord. We're here to help!
Last Updated: November 2025