← Back to archive

Repo of the Day

levelgraph/levelgraph

Published: Jan 19, 2022

Open repository ↗

Graph database JS style for Node.js and the Browser. Built upon LevelUp and LevelDB.

Summary

LevelGraph is a JavaScript graph database that runs on Node.js and in IndexedDB-powered browsers, using LevelDB through the level library as its storage layer. It stores subject-predicate-object triples and follows the Hexastore approach, indexing each triple in six ways to speed up lookups. The project is released under the MIT license and exposes a uniform API for both server and browser code.

What it is useful for

LevelGraph is useful when an engineer needs graph-shaped queries without standing up a dedicated graph server. Because it sits on LevelDB, it works in-process, can be embedded in CLI tools, and can run inside a browser via IndexedDB, which the README highlights as uncommon for graph databases. It fits small knowledge graphs, social-style "friend of a friend" traversals, RDF data, configuration relationships, or any data naturally modeled as triples that needs pattern matching. The Hexastore design lets it answer lookups from any of the six index permutations, so queries that fix one or two of subject, predicate, and object are well supported.

Documented limitations worth keeping in mind: there is no in-place update, so changing a triple requires deleting and re-inserting it. The reverse option works only on get() and getStream(), not on search(). Out of the box, LevelGraph does not parse RDF, it just stores triples; loading N3/Turtle or JSON-LD requires the LevelGraph-N3 or LevelGraph-JSONLD extensions. The README also lists live searches and additional operators (grouping, more filtering) as open TODO items.

How engineers can use it

On Node.js, install with npm install --save levelgraph and create a database by wrapping a Level instance:

var { Level }  = require("level");
var levelgraph = require("levelgraph");
var db = levelgraph(new Level("yourdb"));

The core data model is a triple, for example { subject: "a", predicate: "b", object: "c" }. Use db.put(triple) to insert and db.get({ subject: "a" }) to pattern-match, either as a callback or via db.getStream(...). Multi-step queries use db.search with variables from db.v("x"); the README's example walks a "matteo → friend → ? → friend → ? → friend → davide" path and returns solutions like { x: 'daniele', y: 'marco' }.

For more compact traversals, the Navigator API offers a fluent style: db.nav("matteo").archIn("friend").archOut("friend").solutions(cb). For RDF ingestion, wrap the database with LevelGraph-N3 and/or LevelGraph-JSONLD. Per the README, testing is only validated on Node.js 18 and 20, so other runtimes may need extra care.