// STRYKE-NEO4J — ENGINEERING REPORT

Opt-in stryke connector package · cdylib libstryke_neo4j (publish=false) · namespace Neo4j · JSON-in/JSON-out FFI over dlopen

>_EXECUTIVE SUMMARY

stryke-neo4j is an opt-in connector package in the stryke ecosystem — a Neo4j graph client exposing parametrized Cypher query and run, scalar/row helpers, and schema introspection as the Neo4j package, built on neo4rs, the pure-Rust Bolt driver.

neo4rs is async and pulls in tokio plus a TLS stack — a dependency tree that ships once, on demand, as an opt-in package. stryke core is never linked against it; the cdylib presents a blocking facade so every Neo4j::* call is an ordinary blocking call.

Neo4j
stryke namespace
opt-in
Tier
cdylib
Load model (dlopen)
Bolt
Transport (neo4rs)
44
Functions / FFI exports
9
Capability groups
4.x / 5.x
Neo4j compatibility
MIT
License

~ARCHITECTURE

A single in-process cdylib. The stryke side is a thin .stk library; the heavy driver code lives in libstryke_neo4j and is dlopened on first use Neo4j. No sidecar process, no fork per call.

LayerImplementation
stryke library (lib/Neo4j.stk)Thin wrappers exposing typed functions; serialize args to JSON, decode responses, die on an {error} payload
cdylib (libstryke_neo4j)Rust async (neo4rs/tokio); each neo4j__* export takes a JSON string and returns a JSON string
Blocking facadeOne shared tokio runtime; every handler block_ons the async Bolt call, so the FFI surface is synchronous
Persistent stateOne Graph connection pool cached per (uri, user, db); a pool whose call errors is evicted and reopened on the next call
FFI safetyHandler errors and panics are caught and surfaced as {"error": ...}; a panic never crosses the C ABI into the host shell
BuildCargo crate-type = ["cdylib"], publish = false; ships via s pkg install -g .
CIGitHub Actions .github/workflows/ci.yml — check, fmt, clippy -D warnings, test (ubuntu + macos), doc, release-build on three targets

~CAPABILITIES

The surface is scoped to "useful from a shell pipeline" — parametrized Cypher plus schema introspection, not full driver coverage.

GroupFunctionsNotes
Livenessversion, ping, server_infoRETURN 1 probe; dbms.components()
Queryquery, query_one, scalar, query_values, query_columnRows keyed by RETURN aliases; first-column / named-column list
Writerun, batchSingle statement, or a list in one transaction (commit/rollback)
Graph helperscreate_node, merge_node, set_props, get_node, exists_node, create_rel, merge_rel, delete_rel, delete_node, delete_nodes, degree, node_count, relationship_count, count_property_valuesScalar props; labels/types backtick-quoted (injection-safe); portable counts (no size()/COUNT{})
Schemacreate_index, create_constraint, drop_index, drop_constraintIndex + uniqueness-constraint management (IF NOT EXISTS / IF EXISTS)
Introspectionlabels, relationship_types, property_keys, indexes, constraints, databasesdb.labels(), db.relationshipTypes(), db.propertyKeys(), SHOW INDEXES, SHOW CONSTRAINTS, SHOW DATABASES
Planningexplain, profileEXPLAIN (plan only) / PROFILE (plan + runtime stats)
Cypher helpersescape, quote_literal, quote_ident, format_value, valid_identifierPure; single-quote / backtick quoting + literal formatting (unit-tested)
URL helpersparse_url, redact_url, build_urlPure; Bolt-URI parse / password redaction / reconstruction

Every one of the 44 functions is a thin .stk wrapper over a matching neo4j__* cdylib export — the wrapper count, the export list in stryke.toml, and the #[no_mangle] functions in src/lib.rs are kept in lockstep (44 / 44 / 44).


$WHY OPT-IN (NOT BUILTIN)

neo4rs pulls in tokio and a TLS stack. The core stryke binary stays slim precisely because each connector ships separately. Daily-driver work — one-liners, awk replacement, data scripting — doesn't need a Bolt driver or a graph client linked in.


&FFI PROTOCOL

JSON in, JSON out, over a C ABI. Each request is a JSON object of op-specific args; $name Cypher params are bound positionally, never interpolated into the query text. Each response is a JSON object; errors carry an error field. The C string returned by every export is freed through the shared stryke_free_cstring symbol.

neo4j__query('{"cypher":"MATCH (p:Person) WHERE p.id = $id RETURN p.name AS name",
              "params":{"id":1},"uri":"neo4j://localhost:7687","user":"neo4j"}')
  -> {"rows":[{"name":"Ada"}]}

# handler errors are surfaced, never thrown across the ABI
neo4j__query('{}')  ->  {"error":"missing cypher"}

/SCOPE

See the README's API reference and usage sections for the authoritative scope. The package is intentionally narrower than the underlying driver — the goal is "useful from a shell pipeline", not "complete API coverage". Live, credential-backed round-trips are exercised against a real Neo4j via the gated t/ tests.


+DEPENDENCIES

The crate is deliberately small: the Bolt driver plus a tokio runtime, JSON serialization for the FFI boundary, and the usual error / lazy-init helpers. Chosen for durability over fashion.

CrateVersionRole
neo4rs0.8Pure-Rust Bolt protocol driver — query execution, transactions, row deserialization
tokio1 (rt, rt-multi-thread, net, time, sync)Async runtime the cdylib block_ons for the blocking facade
serde / serde_json1 (derive; preserve_order)JSON encode/decode at the FFI boundary; row column order preserved
anyhow1Error propagation surfaced as {"error": ...}
once_cell1Lazily-built shared runtime + per-connection graph-pool cache

The release profile is tuned for a small, fast artifact: opt-level = 3, thin LTO, one codegen unit, symbols stripped, panic = "abort".


%TESTING

Two test tiers. The Rust unit tests in src/lib.rs cover the pure logic with no database — connection-key defaults, Bolt-URI parse / redact / build round-trips, identifier backtick-quoting (including injection attempts), string escaping, Cypher literal formatting, identifier validation, and the scalar-only property guard. The stryke t/ tests assert the full wrapper surface resolves via use Neo4j and exercise the pure URI helpers; the graph round-trips (write / query / point lookups / relationships / degree / counts / delete) are gated on $NEO4J_URL so CI without a server stays green.

CI runs cargo build, cargo fmt --check, cargo clippy -D warnings, cargo test on ubuntu + macos, a doc build, and a release build across targets. A set of documentation gates pins this site's HTML hygiene — valid structure, https-only links, no inline event handlers, no placeholder hrefs, rel="noopener" on every target="_blank", and a trailing newline.


#PROJECT METADATA

ItemValue
LicenseMIT
Repositorygithub.com/MenkeTechnologies/stryke-neo4j
Parent languagestrykelang
Meta umbrellaMenkeTechnologiesMeta
Issuesgithub.com/MenkeTechnologies/stryke-neo4j/issues