Skip to main content

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.

How-to~5 min

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.

  1. Pick a runtime
    Choose 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
  2. Install the package
    Run 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
  3. Open an in-memory database
    Call 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
  4. Run a Cypher query
    Execute CREATE (:Person {name: 'Ada'}) followed by MATCH (p:Person) RETURN p.name to confirm the install works end-to-end.
    Jump to section
  5. Add persistence when ready
    Save 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:

QuestionRecommendation
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​

SurfaceExtra requirements
Node / TSNode.js 18+ for the published package; Node.js 20+ for repo-local workspace tooling
PythonPython 3.8+; maturin only when building from source
WASMNode.js 20+ for bundling/testing
GoGo 1.21+, cgo enabled, C toolchain, and liblora_ffi
RubyRuby 3.1+, Bundler, and a native build toolchain
Rust / server from sourceRust 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​

PlatformPackageInstallGuide
Node / TSnpmnpm install @loradb/lora-nodeNode →
PythonPyPIpip install lora-pythonPython →
Browser / WASMnpmnpm install @loradb/lora-wasmWASM →
Gopkg.go.devgo get github.com/lora-db/lora/crates/bindings/lora-goGo →
RubyGemgem install lora-rubyRuby →
tip

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 / CLINode.js
Build in Python (sync or asyncio)Python
Run in the browser / Web Worker / edgeWASM
Build a Go service or CLI (cgo)Go
Ship a Ruby app, worker, or Rails serviceRuby
Evaluate from a shell or another languageHTTP 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-database directly in a Rust binary for the lowest-overhead option. crates.io
  • HTTP server — run lora-server and POST /query from any language.

Creating a Client / Connection​

Every binding exposes the same two primitives:

  1. A Database with execute(query, params?).
  2. 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.name

In 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 to createDatabase('app', { databaseDir: './data' }).
  • On lora-node, use openWalDatabase({ 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 / DatabaseDir option for .loradb archives, or use open_wal / OpenWal for 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_snapshot exist on every binding (byte-based on WASM). Continuous durability via WAL exists on every filesystem-backed binding: Rust, lora-node, Python, Go, Ruby, and lora-server. WASM remains snapshot-only. See Limitations → Storage.
  • No query cancellation. Once dispatched, queries run to completion. Keep queries bounded (LIMIT, *..N caps).
  • Parameters, not string interpolation. The only safe way to mix untrusted input into a query.

See also​