Install and Set Up LoraDB
Overview
LoraDB is one Rust engine with bindings for the major application runtimes — Node.js, Python, WebAssembly, Go, and Ruby — plus a standalone HTTP server and direct embedding from Rust. Every binding shares the same parser, planner, executor, and result shape, so switching hosts later is a mechanical translation. This page helps you pick; each binding guide covers install, connect, execute, and error handling end-to-end.
If you only want to try the query surface first, start with the browser playground. It runs LoraDB through WASM without installing a package.
Install LoraDB and run your first query
The shortest happy path: pick the binding for your runtime, install one package, open an in-memory handle, and run a Cypher query.
- Pick a runtimeChoose the binding that matches your host: Node.js, Python, WebAssembly in the browser, Go, Ruby, the lora-database Rust crate for direct embedding, or the lora-server HTTP service. Every binding wraps the same engine.Jump to section
- Install the packageRun npm install @loradb/lora-node, pip install lora-python, npm install @loradb/lora-wasm, go get github.com/lora-db/lora/crates/bindings/lora-go, gem install loradb, or cargo add lora-database depending on the runtime you picked.Jump to section
- Open an in-memory databaseCall Database.create() (Node, Python, Ruby) or its equivalent in your binding. The handle starts with an empty graph and is safe to share across threads / async tasks.Jump to section
- Run a Cypher queryExecute CREATE (:Person {name: 'Ada'}) followed by MATCH (p:Person) RETURN p.name to confirm the install works end-to-end.Jump to section
- Add persistence when readySave the graph with a snapshot (saveSnapshot / save_snapshot_to) or open with WAL-backed durability for continuous persistence. Snapshots are atomic on rename; WAL replays above the snapshot fence on recover.Jump to section
First-time checklist
Before choosing an install path, decide three things:
| Question | Recommendation |
|---|---|
| Do you need parameters for user input? | Use any binding or HTTP /query with params. Never interpolate raw input into query text. |
| Should data survive process restarts? | Open a named .loradb archive, save snapshots, or use a WAL-backed open. Plain in-memory handles are scratch graphs. |
| Will the graph be reachable over a network? | Prefer an in-process binding. If you use lora-server, keep it on 127.0.0.1 or put auth, TLS, and rate limiting in front. |
The shortest happy path for most app developers is: install the binding for your host language, run the minimal example in that guide, then add persistence only when the prototype needs it.
Installation / Setup
Requirements by surface
| Surface | Extra requirements |
|---|---|
| Node / TS | Node.js 18+ for the published package; Node.js 20+ for repo-local workspace tooling |
| Python | Python 3.8+; maturin only when building from source |
| WASM | Node.js 20+ for bundling/testing |
| Go | Go 1.21+, cgo enabled, C toolchain, and liblora_ffi |
| Ruby | Ruby 3.1+, Bundler, and a native build toolchain |
| Rust / server from source | Rust 1.87+ through rustup |
Published packages hide most native build steps. Repo-local development needs the toolchains above because the bindings compile the Rust engine.
Pick a platform
| Platform | Package | Install | Guide |
|---|---|---|---|
| Node / TS | npm install @loradb/lora-node | Node → | |
| Python | pip install lora-python | Python → | |
| Browser / WASM | npm install @loradb/lora-wasm | WASM → | |
| Go | pkg.go.dev | go get github.com/lora-db/lora/crates/bindings/lora-go | Go → |
| Ruby | gem install lora-ruby | Ruby → |
Click any badge to jump to its package-registry page. Each platform guide also documents repo-local build steps for contributors working from a clone.
Which to pick?
| If you… | Pick |
|---|---|
| Ship a Node server / CLI | Node.js |
| Build in Python (sync or asyncio) | Python |
| Run in the browser / Web Worker / edge | WASM |
| Build a Go service or CLI (cgo) | Go |
| Ship a Ruby app, worker, or Rails service | Ruby |
| Evaluate from a shell or another language | HTTP server |
All bindings share the same query surface and result shape — the Cypher is identical, only the host-language wrapper differs.
Rust and HTTP server
Two more paths share the same Cypher surface:
- Rust crate — embed
lora-databasedirectly in a Rust binary for the lowest-overhead option. - HTTP server — run
lora-serverandPOST /queryfrom any language.
Creating a Client / Connection
Every binding exposes the same two primitives:
- A
Databasewithexecute(query, params?). - A result:
{ columns, rows }, where each row maps column name → typed value.
See each platform guide for the language-specific shape.
Running Your First Query
CREATE (:Person {name: 'Ada'})MATCH (p:Person) RETURN p.nameIn any binding that's two execute calls; the platform guide shows
the language-specific syntax.
Examples
Shared value model
Typed values follow one contract (defined in
crates/bindings/shared-ts/types.ts): primitives, lists/maps, graph entities
(tagged {kind: "node" | "relationship" | "path"}), temporals
(tagged {kind: "date" | "datetime" | ...}), and points (tagged
{kind: "point", srid, crs, ...}).
See Data Types Overview for the full catalogue and each binding's parameters section for how host values map in.
Common Patterns
One process, one graph
Each binding defaults to one process, one in-memory graph.
Auto-commit reads on the same handle can overlap on snapshots; write commits
and explicit read-write transactions serialize. Spawn multiple Database
instances only when you intentionally want separate graphs or archives.
If you want persistence, opt into it explicitly:
- On
lora-node, pass a database name and database directory tocreateDatabase('app', { databaseDir: './data' }). - On
lora-node, useopenWalDatabase({ walDir: './data/wal' })for an explicit WAL directory. - On Rust /
lora-server, configure a WAL directory. - On Python, Go, and Ruby, pass a database name plus their
database_dir/DatabaseDiroption for.loradbarchives, or useopen_wal/OpenWalfor an explicit WAL directory.
Bulk-load from the host
The idiomatic large-write shape across every binding is
UNWIND $rows AS row CREATE ….
The $rows parameter comes from a plain list in the host language.
Share a database across modules
Wrap the handle in whatever sharing primitive your language provides
— Arc in Rust, a module singleton in Node/Python, a Worker in the
browser.
Error Handling
Every binding exposes two error layers:
- Query-level errors — parse, semantic, or runtime — surface the engine's message. Typical cases live in Troubleshooting.
- Connection / host-level errors — language-specific (HTTP status, FFI exceptions, spawn failures). Each platform guide covers its own.
Performance / Best Practices
- Persistence depends on the binding. Point-in-time snapshots via
save_snapshot/load_snapshotexist on every binding (byte-based on WASM). Continuous durability via WAL exists on every filesystem-backed binding: Rust,lora-node, Python, Go, Ruby, andlora-server. WASM remains snapshot-only. See Limitations → Storage. - No query cancellation. Once dispatched, queries run to
completion. Keep queries bounded (
LIMIT,*..Ncaps). - Parameters, not string interpolation. The only safe way to mix untrusted input into a query.
See also
- Ten-Minute Tour — guided walkthrough.
- Graph Model — what lives in the graph.
- Query Examples — copy-paste recipes.
- Cookbook — scenario-based recipes.
- Data Types — values and parameters.
- Troubleshooting — when something goes wrong.