Introduction
sparq is a lightning-fast RDF triplestore and SPARQL 1.1 / 1.2 engine, written in Rust — usable as a library, CLI, HTTP server, and from Python and JavaScript/WASM.
Status: experimental research engine. The API is unstable and pre-1.0. Conformance against the W3C SPARQL, SHACL, and inference suites is tracked by CI ratchets that only ever go up — generated by
sparq-conformanceand published on every run (inference floor committed atinference-conformance-report.md). SPARQLSERVICEfederation ships behind the opt-inservicecargo feature (off in the default build); when built in it is default-DENY-all egress, allowlisted per host as an SSRF guard (seecrates/sparq-server/README.mdandresearch/roadmap.md).
Where to go next
- Install & build from source — get a working build.
- Capabilities at a glance — what each opt-in surface does.
Per-surface how-to guides live in the
usage skills router, and the full crate
map is in AGENTS.md. Live per-commit
performance metrics are on the
benchmarks dashboard — numbers are deliberately not
baked into these docs, because they drift.
Install or build from source
v0.1.6 release install paths
These are the install commands for the planned v0.1.6 release. Use them only after
the tagged release and corresponding registry publications have succeeded. v0.1.5
published the three npm packages but not the PyPI wheels, and the crates.io bootstrap is
still pending. Until then, build from source.
# Rust CLI and HTTP server
cargo install sparq-cli --version 0.1.6
cargo install sparq-server --version 0.1.6
# Rust libraries (run inside your Cargo project)
cargo add sparq-core@0.1.6 sparq-engine@0.1.6
# Python: distribution name sparq-rdf, import name sparq
python -m pip install sparq-rdf==0.1.6
python -c 'import sparq'
# JavaScript/WASM RDF store
npm install @sparq-org/sparq@0.1.6
# Loopback-only Solid/LDP development host (not a production server)
npm install @sparq-org/solid-server@0.1.6
# eye-js / eyereasoner migration API backed by sparq's N3 reasoner
npm install @sparq-org/eyereasoner-compat@0.1.6
Build from source
sparq is a Rust workspace. The minimum supported Rust version (MSRV) is tracked in CI; a recent stable toolchain works. Build the release binaries, then query a file, build a persistent on-disk store, or run the HTTP server:
cargo build --release
# Query a file (Turtle / N-Triples / N-Quads / TriG, optionally .gz / .bz2 / .zst)
cargo run --release -p sparq-cli -- query data.ttl turtle \
'SELECT ?s ?o WHERE { ?s <http://schema.org/name> ?o } LIMIT 10'
# Build a persistent on-disk store once, then query it without loading into RAM
cargo run --release -p sparq-cli -- build data.nt ntriples ./idx
cargo run --release -p sparq-cli -- query-mmap ./idx 'SELECT (COUNT(*) AS ?n) WHERE { ?s ?p ?o }'
# W3C SPARQL Protocol HTTP server on :3030
cargo run --release -p sparq-server -- --addr 127.0.0.1:3030 --format turtle data.ttl
Use it as a library
The snippet below is not hand-written prose — it is the quickstart region of
crates/sparq-engine/examples/quickstart.rs,
embedded verbatim via mdBook's {{#rustdoc_include}}. That file is compiled and run by
cargo test -p sparq-engine --examples, so this example cannot silently drift from the
public API:
//! sq-384j — Tested library quickstart, embedded into the docs guide.
//!
//! This is the canonical "use sparq as a library" example. The region between the
//! `book/src/getting-started/install.md` via mdBook's `{{#rustdoc_include}}`, so the
//! snippet a reader sees in the guide is a fragment of THIS file — a file that
//! `cargo test -p sparq-engine --examples` actually compiles and runs (see the
//! `#[test]` below). Keep the anchored region self-contained and dependency-light
//! (only `sparq-core` + `sparq-engine`, both already direct deps of this crate) so
//! the guide example stays honest and never drifts from a passing test.
//!
//! Run it directly with:
//! cargo run -p sparq-engine --example quickstart
use sparq_core::Graph;
use sparq_engine::query;
fn count_people(turtle: &str) -> Result<usize, String> {
// Parse RDF (Turtle/N-Triples/N-Quads/TriG) straight from a string.
let graph = Graph::load_str(turtle, "turtle")?;
// Run a SPARQL 1.1 SELECT. The result exposes `vars` (the projected
// variables) and `rows` (each a `Vec<Option<Term>>`, one cell per var).
let result = query(
&graph,
"SELECT ?person WHERE { ?person a <http://schema.org/Person> }",
)?;
Ok(result.rows.len())
}
fn main() {
let turtle = r#"
@prefix schema: <http://schema.org/> .
<http://example.org/alice> a schema:Person .
<http://example.org/bob> a schema:Person .
<http://example.org/acme> a schema:Organization .
"#;
let n = count_people(turtle).expect("query should succeed");
println!("{n} people");
}
#[cfg(test)]
mod tests {
use super::count_people;
// The same code path the docs guide shows, exercised by `cargo test`. If the
// public API drifts, this test (and therefore the embedded guide snippet)
// breaks loudly rather than silently going stale.
#[test]
fn quickstart_counts_people() {
let turtle = r#"
@prefix schema: <http://schema.org/> .
<http://example.org/alice> a schema:Person .
<http://example.org/bob> a schema:Person .
<http://example.org/acme> a schema:Organization .
"#;
assert_eq!(count_people(turtle).unwrap(), 2);
}
}
The contributor gate
If you are working on the engine itself, the gate for landing a change is a green full-workspace build, test, lint, and the conformance / performance ratchets:
cargo build --workspace
cargo test --workspace
cargo clippy --workspace --exclude sparq-py --all-targets -- -D warnings
cargo fmt --all --check runs in CI too, but it is informational, not part of the gate:
the one-time workspace reformat is still pending, so the check reports pre-existing diffs in
files you did not touch. Format what you touched and leave the rest.
See CONTRIBUTING.md for the full
contributor workflow and the conformance ratchet details — that file is the canonical source for
the gate.
Capabilities at a glance
The engine core is always built; every capability below is an opt-in crate or feature that the core does not depend on, so the core stays lean. Each links the standard it implements and its usage guide.
- SPARQL query — run SPARQL 1.1 and 1.2 over your data (guide).
- SPARQL Update — insert, delete, and load data with SPARQL 1.1 Update (guide).
- RDF parsing & ingest — load and parse Turtle, N-Triples, N-Quads, and TriG, with
transparent
.gz/.bz2/.zstdecompression (guide). - Rust-native RDF objects — bind a focus term to an owned or borrowed store, traverse outgoing/incoming predicates, and convert typed literal values without handling raw triples (guide).
- RDF 1.2 triple terms — store and query triple terms per RDF 1.2 Concepts (guide).
- Custom extension functions — register your own Rust functions under IRIs and call them in SPARQL (docs/extension-functions.md).
- RDFS / OWL-RL / N3 reasoning — materialise entailments under RDFS, the OWL 2 RL profile, and Notation3 (guide). N3 is measured against the w3c/N3 community-group suite (report); the community notation3tests suite runs in an advisory lane with no published baseline yet.
- SHACL validation — validate graphs against shapes with SHACL (guide).
- Full-text search — index and search RDF literals from SPARQL (guide).
- GeoSPARQL — spatial filters and functions over geometries with OGC GeoSPARQL (guide).
- Vector & similarity search — embedding-based nearest-neighbour and structural similarity over entities (guide).
- Natural-language & GenAI retrieval — schema introspection and grounded NL→SPARQL for LLM agents (guide).
- HDT archives — load compressed HDT datasets (crate).
- RDF stream processing — continuous windowed queries with RSP-QL (guide).
- Solid access control — enforce Solid WAC and ACP authorisation (crate).
- RDF Dataset Canonicalization — deterministic, blank-node-relabelled canonical form for hashing/signing/diffing with RDFC-1.0 (guide).
A note on SPARQL Update 1.1 vs 1.2
SPARQL 1.1 Update is fully supported: INSERT DATA, DELETE DATA, DELETE/INSERT … WHERE
(with USING / WITH), LOAD, CLEAR, CREATE, DROP, COPY, MOVE, and ADD, with
request-level atomicity for ;-separated bodies.
SPARQL 1.2 Update adds no new operations over 1.1;
its substantive change is the RDF 1.2 triple-term
semantics inside INSERT DATA / DELETE DATA and DELETE/INSERT … WHERE — inserting or
deleting a reifying triple (rdf:reifies <<( s p o )>>) operates on that triple term itself and
does not automatically assert or retract the asserted triple it refers to. sparq handles this:
triple terms are stored and matched as structural object terms, so a reifying triple is added or
removed as an exact term with no coupling to its asserted counterpart. This behaviour is exercised
by the engine's write tests (crates/sparq-engine/tests/rdfstar_write.rs); it has not been checked
against a formal SPARQL 1.2 conformance suite.
Research scaffolds (no security guarantee yet)
Two capabilities are research scaffolds. They are honest models of the protocols, but they do
not yet provide the cryptographic guarantee a relying party would need. Treat any engineering
numbers as indicative, not as an audited cryptographic guarantee. The two maturity caveats below
are single-sourced verbatim (build-time {{#include}}) from their canonical guides, so they
cannot drift from the source of truth — see the
zk-query-proofs guide,
the mpc guide, and
SECURITY.md for the full scope.
Zero-knowledge query proofs —
Research-stage / experimental — NOT-yet-sound. The composition verifier's soundness is the subject of an open audit (sq-qhy4 / sq-9hrn; remediation epic sq-1s2): a passing proof is NOT a guarantee the SPARQL statement holds under an adversarial prover. Read the "Honest scope" section before relying on a guarantee — only
Simpleentailment is proved; circuit members are fixed buckets. The query fragment covers BGP scans, integer FILTER (and the integer-valuedxsd:doublefragment), and a single-prover hidden cross-credential JOIN — the JOIN restricted to credentials sharing ONE issuer-signed revocation slot (sq-cuvmj; see "Honest scope").
Federated MPC —
Maturity (read first). EARLY / RESEARCH, native-only (deliberately not in the wasm build). The Shamir layer's reconstruction is RS-consistency-checked: it detects (and, with enough redundancy, robustly corrects) actively-tampered shares and reports the exact guarantee via
BackendInfo.malicious_security— but the degree-2tequality open in the hidden-value join is not hardened atn = 2t+1(see Gotchas). The primitives run as an in-process simulation (one process plays all parties) for correctness/cost counting, AND over a REAL multi-process loopback transport (transportmodule — each party its own process over127.0.0.1; all fourQueryClasscells incl. the multi-round oblivious shuffle/sort run on the wire) for MEASURED wall-clock + bytes-on-wire. The collaborative ZK proof of correctness + issuer-attestation is not implemented: those methods returnMpcError::NotYetImplementednaming their gate. No fake crypto anywhere. See Gotchas for the full envelope.
Interfaces
- Interfaces — a CLI, a SPARQL 1.1 Protocol + Graph Store HTTP Protocol HTTP server, a WebAssembly / JavaScript build, and a Python package, plus a Kubernetes Helm deployment.
Rust crates
These crates are published to crates.io, in lockstep at the workspace version. The first crates.io publication is still pending; until then, build from source.
| Crate | What it is | Usage guide |
|---|---|---|
sparq-core | Store, dictionary, indexes and RDF parsers | SPARQL query |
sparq-engine | SPARQL 1.1/1.2 planner and execution | SPARQL query |
sparq-engine-serialize | Result and RDF serializers used by the engine | SPARQL query |
sparq-engine-service | SERVICE federation client used by the engine | Federated planning |
sparq-substrate | Shared evaluation substrate for engine and reasoner | Substrate |
sparq-jsonld | JSON-LD processing | JSON-LD |
sparq-reason | RDFS / OWL RL / N3 inference | Inference |
sparq-shacl | SHACL Core + SPARQL validation | SHACL validation |
sparq-hdt | HDT archive loading | Data formats |
sparq-serve | Serving layer under the HTTP server | HTTP server |
sparq-server | SPARQL 1.1 Protocol / Graph Store HTTP server | HTTP server |
sparq-cli | The sparq command-line tool | CLI |
The SPARQL parser ships as sparq-spargebra,
oxigraph's spargebra with sparq's conformance and hardening patches.
Every other capability (full-text, GeoSPARQL, vectors, Solid access control, ZK proofs,
policy, HTTP/3, ...) lives in crates that are built from the repository rather than from
crates.io, and the published sparq-server and sparq-cli omit the features that need them.
Build from source with the feature enabled to use one; see the
release runbook.