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