The Problem
Applications that need sub‑millisecond graph traversals often resort to heavyweight databases (JVM‑based, Docker containers, external processes). Those runtimes add latency, memory pressure, and operational complexity, especially when the graph is embedded in a service written in Rust, Python, or JavaScript.
What This Does
grafeo is a pure‑Rust graph engine that can be linked as a library or launched as a standalone server. It stores Labeled Property Graph and RDF data with MVCC snapshot isolation and supports six query languages (GQL, Cypher, Gremlin, GraphQL, SPARQL, SQL/PGQ). The core lives in crates/grafeo-core (not listed but part of the 781‑file crates tree) and is exposed through language bindings in crates/bindings/* (C, Python, Node, Go, C#, Dart, WASM).
- Build artefacts* –
Cargo.tomlat the repository root drives the Rust compilation; each binding crate has its ownCargo.toml(e.g.,crates/bindings/python/Cargo.toml). - Distribution* – pre‑built wheels, npm packages, and a NuGet feed are generated by the CI workflows referenced in the README badges.
How It Is Wired
Execution begins at the language‑specific entry points:
- Python –
crates/bindings/python/src/lib.rsregisters thegrafeomodule; the first call from user code reachescreate_edge(the most‑called internal function, invoked from 61 places). - Node –
crates/bindings/node/src/lib.rsloads the N‑API addon; the samecreate_edgeroutine is used under the hood. - Rust CLI / library – not listed as a distinct
main, but the library’s public API (execute_query,setup_random_graph, etc.) is called from the test harnesses intests/and from benchmark scripts incrates/bindings/python/tests/bases/bench_algorithms.py.
The internal call graph shows a tight hub around create_edge, _assert_category, and benchmark. Changing any of these functions has the widest blast radius because they are referenced by dozens of callers (e.g., test_verify_shortest_path → create_edge is exercised 24 times).
File‑level responsibilities (high‑traffic examples):
| File | Core responsibility | Calls / effects |
|---|---|---|
crates/bindings/python/tests/lpg/gql/test_regression_external.py | End‑to‑end GQL regression suite | 135 functions, reads/writes DB |
crates/bindings/python/tests/bases/bench_storage.py | Benchmark harness for storage back‑ends | 71 functions, invoked by 38 other files |
crates/bindings/python/src/database.rs | Python‑side DB wrapper (oversized, 1864 lines) | Direct DB calls, high cognitive load |
The repository contains no circular module dependencies (13 import edges, 0 cycles), which limits the risk of dead‑ends when refactoring. However, the deepest nesting reaches 9 levels in files such as crates/bindings/python/src/database.rs, making the control flow harder to follow.
How To Use It
# Clone and build the Rust core
git clone https://github.com/moses-y/grafeo
cd grafeo
cargo build --release # builds all crates, including bindings
# Python binding (local development)
cd crates/bindings/python
maturin develop --release # builds the PyO3 extension in place
python -c "import grafeo; print(grafo.version())"
# Node binding (local development)
cd crates/bindings/node/npm
npm install # pulls pre‑built binaries or builds from source
node -e "const g = require('@grafeo-db/js'); console.log(g.version())"
The CI workflows (.github/workflows/*.yml) already verify that the Rust library compiles, the Python wheel builds, and the npm packages publish, so the same commands can be used for local verification.
Real‑World Use
A microservice written in Python can embed Grafeo for real‑time recommendation:
import grafeo
db = grafeo.Database(in_memory=True)
db.execute_query("CREATE (:User {id: 1})-[:FOLLOWS]->(:User {id: 2})")
paths = db.execute_query("MATCH p = (a)-[:FOLLOWS*]->(b) RETURN p LIMIT 5")
print(paths)
Because the engine runs in‑process, latency stays sub‑millisecond and memory usage is a fraction of comparable JVM graph stores.
Code Health & Issues
- High – GitHub Actions use mutable tags (
@vN). Pin each action to a commit SHA. - High – Critical steps in
.github/workflows/release.ymldiscard exit codes or usecontinue-on-error, masking failures. Remove those flags. - High – No dependency‑vulnerability scan in CI. Add
dependency-review-actionorosv-scanner. - Medium – Checkout step retains the GitHub token; set
persist-credentials: falseand pass a token only where needed. - Medium – Workflow jobs lack explicit
timeout-minutes; add reasonable limits. - High – Deep nesting (57 occurrences, e.g.,
crates/bindings/python/src/database.rs). Refactor into guard clauses or smaller functions. - High – Duplicated 6‑line blocks across 399 files (e.g., header definitions in
grafeo.h). Consolidate into shared helpers. - High – Oversized files (
database.rsin C and Python bindings, each ~1864 lines). Split by responsibility.
No critical security findings, license (Apache-2.0) and lockfiles are present, and the test suite (461 files) runs in CI.
The Bottom Line
Grafeo delivers a high‑performance, embeddable graph engine with broad language support and a solid CI pipeline. The codebase is well‑tested but suffers from deep nesting, duplicated snippets, and a few CI hygiene issues that should be addressed before large‑scale production adoption. Teams comfortable with Rust and willing to invest in modest refactoring will find Grafeo a strong alternative to heavyweight graph databases.