API reference
Every relate surface, from the CLI and the language clients to the served protocols, with the capability matrix and each surface's reference page.
clirustcpythonnodebrowserjavagoswiftbolthttpmcp
relate is one engine with several front doors, and each front door is a surface Any front door to the relate engine: the CLI, a language client, the C ABI, the WebAssembly build, or a server that relate serve hosts. Read more in the glossary. The Rust crate is the engine. The C library, librelate_ffi, exposes it through a C application binary interface (C ABI), which the Node.js, Java, Go and Swift client A language package that runs the relate engine inside a program's process: the Python, Node.js, Rust, Java, Go and Swift clients. Read more in the glossary call; the Python client and the WebAssembly (WASM) browser build carry the engine themselves. The relate CLI links the engine too, and relate serve hosts Bolt Neo4j's binary client protocol; relate serve --bolt <port> speaks it, so Neo4j's drivers and Neo4j Browser can run statements against a relate store. Read more in the glossary, the HTTP Query API and MCP The Model Context Protocol, which agent hosts use to call tools; relate serve --mcp exposes a store as read_cypher, get_schema and write_cypher. Read more in the glossary over one store A relate database: a directory, a single .rl file, or :memory:, opened with --database. Read more in the glossary. Every surface runs the same engine, so a statement means the same thing on each; the surfaces differ in what they expose around it, which the matrix on this page records.
Synopsis
| Surface | Package or command | An in-memory store |
|---|---|---|
| CLI | relate | --database :memory:, the default |
| Python | relate-db | relate.connect(":memory:") |
| Node.js | @relate/relate | Database.open(":memory:") |
| Browser | @relate/relate-wasm | new RelateDb() |
| Rust | the relate crate | Database::open(":memory:") |
| C | librelate_ffi, relate.h | relate_database_open(":memory:", …) |
| Java | com.relate:relate | Database.open(":memory:") |
| Go | github.com/relatedb/relate/clients/go | relate.Open(":memory:") |
| Swift | Relate | Database.inMemory() |
| Bolt, HTTP, MCP | relate serve | relate serve --database :memory: --http <port>; at least one of --http, --bolt or --mcp is required |
Package names are launch-day targets; Project lists the platforms each one ships for.
Capability matrix
| Feature | CLI | Python | Node.js | Browser (WASM) | Rust | C | Java | Go | Swift | Bolt | HTTP | MCP |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| In-memory storeA store that lives only in the process. | yes--database :memory:, the default | yesrelate.connect(":memory:") | yesDatabase.open(":memory:") | yesnew RelateDb() | yesDatabase::open(":memory:") | yesrelate_database_open(":memory:", …) | yesDatabase.open(":memory:") | yesrelate.Open(":memory:") | yesDatabase.inMemory() | yesrelate serve --database :memory: --bolt <port> | yesrelate serve --database :memory: --http <port> | yesrelate serve --database :memory: --mcp stdio |
| Directory storeA store in a directory on disk. | yes--database ./dir | yesrelate.connect(path) | yesDatabase.open(path) | nono filesystem paths; RelateDb.open("opfs://<name>") is the durable browser store, in a dedicated worker | yesDatabase::open(path) | yesrelate_database_open(path, …) | yesDatabase.open(path) | yesrelate.Open(path) | yesDatabase(path:) | yesrelate serve on a directory store | yesrelate serve on a directory store | yesrelate serve on a directory store |
Single-file .rl storeA store in one .rl file. | yes--database ./graph.rl | yesrelate.connect("graph.rl") | yesDatabase.open("graph.rl") | noopens :memory: and opfs:// only | yesDatabase::open("graph.rl") | yesa *.rl URI | yesDatabase.open("graph.rl") | yesrelate.Open("graph.rl") | yesDatabase(path: "graph.rl") | yesrelate serve on a .rl store | yesrelate serve on a .rl store | yesrelate serve on a .rl store |
| Read-only openAn open that loads the store once and refuses every write. | yes--read-only; a write exits 6 | yesread_only=True | yesDatabase.open(uri, { readOnly: true }) | yesnew RelateDb(true) | yesOpenMode::ReadOnly | yesrelate_database_open_read_only | yesDatabase.openReadOnly(uri) | yesrelate.OpenReadOnly(uri) | yesDatabase(readOnlyPath:) | yesrelate serve --read-only | yesrelate serve --read-only | yesrelate serve --mcp stdio --read-only; only read_cypher and get_schema are listed |
| Explicit transactionsSeveral statements committed or rolled back together. | yes.begin, .commit, .rollback in a script on stdin or the shell | yesautocommit = False, then commit() or rollback() | yesbegin(), commit(), rollback() | noeach statement commits on its own; BEGIN is a syntax error | yesbegin(), commit(), rollback() | yesrelate_conn_begin, relate_conn_commit, relate_conn_rollback | yesbegin(), commit(), rollback() | yesBegin(), Commit(), Rollback() | yesbegin(), commit(), rollback(), transaction { } | yesBEGIN, COMMIT, ROLLBACK | yesPOST /db/<name>/query/v2/tx, then …/tx/<id>/commit | noeach tools/call runs one statement |
Parameters$name values passed beside the statement. | yes--param name=value | yesexecute(statement, {"x": 3}) | yesquery(statement, { x: 3 }) | yesexecute(statement, paramsJson) | yesquery_with_params | yesthe params builder | yesquery(statement, Map) | yesQueryParams(statement, map) | yesquery(statement, [String: CypherValue]) | yesthe RUN message's parameter map | yes"parameters" in the request body | yesthe tools' parameters argument |
| Column types, counters and timingsMetadata returned with each result. | partialthe envelope has columnTypes, timings (elapsed and its phase split) and planCache, and the plan on EXPLAIN; no counters | yesQueryResult (column_types, stats, query_type, elapsed_ms and its phase split) and the result summary | partialcounters, query type, elapsed and its phase split; no per-column type list (each value carries its type) | yescolumnTypes, stats, elapsed_ms and its phase split, plan_cache in the envelope | yesQueryResult: header.column_types, header.query_type, stats, elapsed_ms() and its phase split, plan_cache() | partialcounters, timings and column names; no column-type call (read each value's kind with relate_value_kind) | partialquery type (a typed QueryType), namespace, bookmark, notifications and plan; no column types, counters or timings | partialStats, QueryType, Plan; no column types or timings | partialstats, elapsedMs and its phase split, queryType; no column types | yesthe SUCCESS summaries: columnTypes, t_first, t_last, the phase times, plan_cache, type, stats | partialcounters on a write, queryPlan, timings (elapsed and its phase split) and planCache; no column types in the JSON response | yescolumnTypes, stats, elapsed_ms and its phase split, plan_cache in the tool result |
| NotificationsThe engine's query notifications (for example a Cartesian product), each with a remedy. | yesnotifications in the envelope; filled on EXPLAIN and PROFILE | yesQueryResult.notifications | yesresult.notifications | yesnotifications in the envelope; filled on EXPLAIN and PROFILE | yeswith the plan, on EXPLAIN and PROFILE | yesrelate_result_notifications | yesgetNotifications() | yesNotifications | yesnotifications | yesin the ending SUCCESS summary on EXPLAIN and PROFILE; a plain run carries none | yesnotifications in the response on EXPLAIN and PROFILE only; the remedy is appended to description | yeson every call, from the EXPLAIN that classifies the statement |
| Arrow outputResults as Apache Arrow. | nono Arrow output mode | yescursor.to_arrow() (the relate-db[arrow] extra), Database.execute_arrow() | nono Arrow call in the client | nono Arrow call in the package | yesthe relate-arrow crate | nono Arrow call in the client | nono Arrow call in the client | nono Arrow call in the client | nono Arrow call in the client | nono Arrow output on this surface | nono Arrow output on this surface | nono Arrow output on this surface |
| Change data captureReading committed changes from a slot. | nono CDC command; CALL db.cdc.current() is ProcedureNotFound | nono change-data-capture call in the client | nono change-data-capture call in the client | noCALL db.cdc.current() is ProcedureNotFound | yesregister_cdc_slot, cdc_records_after, ack_cdc_slot | nono change-data-capture call in the client | nono change-data-capture call in the client | nono change-data-capture call in the client | nono change-data-capture call in the client | nono change-data-capture feed on this surface; CALL db.cdc.current() is ProcedureNotFound | nono change-data-capture feed on this surface; CALL db.cdc.current() is ProcedureNotFound | nono change-data-capture feed on this surface; CALL db.cdc.current() is ProcedureNotFound |
Vector searchVector indexes and SEARCH. | yesCREATE VECTOR INDEX and SEARCH | yesCREATE VECTOR INDEX and SEARCH | yesCREATE VECTOR INDEX and SEARCH | yesCREATE VECTOR INDEX and SEARCH | yesCREATE VECTOR INDEX and SEARCH; the engine crate the other surfaces build on | yesCREATE VECTOR INDEX and SEARCH through the C ABI | yesCREATE VECTOR INDEX and SEARCH through the C ABI | yesCREATE VECTOR INDEX and SEARCH through the C ABI | yesCREATE VECTOR INDEX and SEARCH through the C ABI | yesCREATE VECTOR INDEX and SEARCH as statements | yesCREATE VECTOR INDEX and SEARCH | yesCREATE VECTOR INDEX and SEARCH as statements |
| Full-text searchFull-text indexes and their queries. | yesCREATE FULLTEXT INDEX and full-text SEARCH, with the index's query syntax (AND, NOT) | yesCREATE FULLTEXT INDEX and full-text SEARCH | yesCREATE FULLTEXT INDEX and full-text SEARCH | yesCREATE FULLTEXT INDEX and full-text SEARCH | yesCREATE FULLTEXT INDEX and full-text SEARCH; the engine crate the other surfaces build on | yesCREATE FULLTEXT INDEX and full-text SEARCH through the C ABI | yesCREATE FULLTEXT INDEX and full-text SEARCH through the C ABI | yesCREATE FULLTEXT INDEX and full-text SEARCH through the C ABI | yesCREATE FULLTEXT INDEX and full-text SEARCH through the C ABI | yesCREATE FULLTEXT INDEX and full-text SEARCH as statements | yesCREATE FULLTEXT INDEX and full-text SEARCH | yesCREATE FULLTEXT INDEX and full-text SEARCH as statements |
LOAD CSV from local filesLocal LOAD CSV under a configured directory (denied unless one is set). | yes--load-csv-dir PATH or RELATE_LOAD_CSV_DIR | yesRELATE_LOAD_CSV_DIR; connect takes no CSV option | yesRELATE_LOAD_CSV_DIR | nono CSV directory can be set; a local file is LOAD CSV file unavailable | yesOpenOptions.load_csv_dir | yesRELATE_LOAD_CSV_DIR, read by the C ABI's open | yesRELATE_LOAD_CSV_DIR, read by the C ABI's open | yesRELATE_LOAD_CSV_DIR, read by the C ABI's open | yesRELATE_LOAD_CSV_DIR, read by the C ABI's open | yesRELATE_LOAD_CSV_DIR for relate serve, one store for every served surface | yesRELATE_LOAD_CSV_DIR for relate serve, which has no flag for it | yesRELATE_LOAD_CSV_DIR for relate serve; only through write_cypher, which returns no rows (read_cypher refuses LOAD CSV) |
Load a store from a URLOpening a .rl store fetched over https. | yes--load with an https URL to a .rl file | nono open from a URL in the client | nono open from a URL in the client | noopens :memory: and opfs:// only | noDatabase::open takes :memory:, a path or file:// | nono open from a URL in the client | nono open from a URL in the client | nono open from a URL in the client | nono open from a URL in the client | yesrelate serve --database :memory: --load with an https URL; the loaded store is read-only | yesrelate serve --database :memory: --load with an https URL; the loaded store is read-only | yesrelate serve --database :memory: --load with an https URL; the loaded store is read-only |
Agent modeThe CLI's agent defaults: the 100-row cap and the piped toon output. | yes--agent-mode, RELATE_AGENT_MODE, or a detected agent harness | noA CLI setting | noA CLI setting | noA CLI setting | noA CLI setting | noA CLI setting | noA CLI setting | noA CLI setting | noA CLI setting | noA CLI setting | noA CLI setting | noA CLI setting |
Each cell is yes, no, partial or unknown, with the call, flag or reason. Checked on 2026-11-09 against relate 0.1.2: runs of the CLI binary and relate serve (Bolt, HTTP and MCP), the WebAssembly build this site ships, and the Python, Node.js, C, Java, Go, Swift and Rust clients, and each surface's upstream reference. The C, Java, Go and Swift clients load the same C ABI library as the Node.js client.
Each row is a feature and each column a surface; every row has a stable anchor, #matrix-<feature>, such as #matrix-read-only. A cell holds one of four values, then a note:
| Value | Meaning |
|---|---|
yes | The surface has the feature; the note names the call, flag, or field |
no | The surface lacks it; the note says why, or what it offers instead |
partial | The surface has part of it; the note names the part |
unknown | Nobody has checked the cell; the matrix never guesses |
A cell is checked against a run of the surface or its upstream reference, and the note says what the surface does, not how the cell was checked. The C, Java, Go and Swift clients load the same C library as the Node.js client, so a statement-level cell such as vector search is checked once through that library; the Bolt and MCP cells of statement-level features are checked on the store all three served surfaces share. The reference page of each language client shows its own column alone.
Surfaces
- CLI: relate CLI for every command and flag; Script the CLI for using it from shell scripts.
- Python: Python API; Use the Python client.
- Node.js: Node.js API; Use the Node.js client.
- Browser: WebAssembly API; Use relate from a web page.
- Rust: Rust API; Use the Rust crate.
- C: C ABI; Use the C ABI.
- Java: Java API; Use the Java client.
- Go: Go API; Use the Go client.
- Swift: Swift API; Use the Swift package.
- Bolt: Bolt server; Serve a store over Bolt.
- HTTP: HTTP Query API; Serve the HTTP Query API.
- MCP: MCP server; Serve a store over MCP.
See also
- Install relate: the CLI and a package for each language.
- Project: releases, platforms and where each package is published.
- Errors: the error codes every surface shares.
- Architecture: how the engine and its surfaces fit together.
- Embedded graph in an app: the problem the language clients solve.