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-conformance and published on every run (inference floor committed at inference-conformance-report.md). SPARQL SERVICE federation ships behind the opt-in service cargo feature (off in the default build); when built in it is default-DENY-all egress, allowlisted per host as an SSRF guard (see crates/sparq-server/README.md and research/roadmap.md).

Where to go next

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 / .zst decompression (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 Simple entailment is proved; circuit members are fixed buckets. The query fragment covers BGP scans, integer FILTER (and the integer-valued xsd:double fragment), 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-2t equality open in the hidden-value join is not hardened at n = 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 (transport module — each party its own process over 127.0.0.1; all four QueryClass cells 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 return MpcError::NotYetImplemented naming their gate. No fake crypto anywhere. See Gotchas for the full envelope.

Interfaces

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.

CrateWhat it isUsage guide
sparq-coreStore, dictionary, indexes and RDF parsersSPARQL query
sparq-engineSPARQL 1.1/1.2 planner and executionSPARQL query
sparq-engine-serializeResult and RDF serializers used by the engineSPARQL query
sparq-engine-serviceSERVICE federation client used by the engineFederated planning
sparq-substrateShared evaluation substrate for engine and reasonerSubstrate
sparq-jsonldJSON-LD processingJSON-LD
sparq-reasonRDFS / OWL RL / N3 inferenceInference
sparq-shaclSHACL Core + SPARQL validationSHACL validation
sparq-hdtHDT archive loadingData formats
sparq-serveServing layer under the HTTP serverHTTP server
sparq-serverSPARQL 1.1 Protocol / Graph Store HTTP serverHTTP server
sparq-cliThe sparq command-line toolCLI

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.