An interactive knowledge graph browser with guided tours. Graph data is declared in data/config.json and loaded from RDF graph sources.
Demo: https://lambdasistemi.github.io/graph-browser/
- Force-directed graph layout (fCoSE) with adaptive spacing
- Click to focus, depth controls (1/2/3/All) for neighborhood size
- Hover nodes and edges for descriptions
- Full-text search across all labels and descriptions
- Guided tours with narrative text and inline links
- Fully data-driven: title, kinds, colors, shapes all from config
- Universal viewer: browse any repo's graph via
?repo=owner/repo - Repo management: add, switch, and delete repos from a left panel
- Per-repo state: each repo remembers selected node, depth, tutorial progress
- Dual output:
lib(embeddable viewer) andapp(hosted universal viewer) - Deep-linking: share
?repo=owner/repoURLs that auto-load - Token support: encrypted storage for private repo access
- Prompt builder: generate context-rich prompts to improve nodes and edges via PR
- Views: named subgraph lenses — filter a shared node/edge catalog by topic with per-view tours
- Self-documenting: graph-browser's own architecture is browsable as a graph with views
- CI validation action: reusable GitHub Action to validate any data repo
- Build action: assemble a deployable site from graph-browser data with zero build tools
- RDF-first self-graph: graph-browser’s own architecture is authored and served from RDF graph sources
- RDF export: derive Turtle and N-Quads from the authored graph model through the Oxigraph FFI path
Your repository needs a data/ directory with:
{
"title": "My Knowledge Graph",
"description": "What this graph is about.",
"sourceUrl": "https://github.com/you/your-repo",
"graphSources": [
{ "format": "text/turtle", "path": "data/rdf/graph.ttl" },
{ "format": "text/turtle", "path": "data/rdf/core-ontology.ttl" },
{ "format": "text/turtle", "path": "data/rdf/application-ontology.ttl" }
],
"kinds": {
"concept": { "label": "Concept", "color": "#79c0ff", "shape": "round-octagon" },
"entity": { "label": "Entity", "color": "#58a6ff", "shape": "ellipse" }
}
}config.json is the stable entry point. It supplies viewer metadata, node kind styling, and the ordered RDF graph sources to load.
Use graphSources for the primary graph plus ontology layers:
{
"title": "My Knowledge Graph",
"description": "What this graph is about.",
"sourceUrl": "https://github.com/you/your-repo",
"graphSources": [
{ "format": "text/turtle", "path": "data/rdf/graph.ttl" },
{ "format": "text/turtle", "path": "data/rdf/core-ontology.ttl" },
{ "format": "text/turtle", "path": "data/rdf/application-ontology.ttl" }
],
"kinds": {
"concept": { "label": "Concept", "color": "#79c0ff", "shape": "round-octagon" }
}
}graphSources is loaded in order and merged into one runtime dataset for both rendering and SPARQL queries.
The current runtime importer supports RDF syntaxes understood by Oxigraph, including Turtle, JSON-LD, and N-Quads. The cleanest machine-oriented option is the exported graph.nq:
{
"title": "My Knowledge Graph",
"description": "What this graph is about.",
"sourceUrl": "https://github.com/you/your-repo",
"graphSources": [
{ "format": "application/n-quads", "path": "data/rdf/graph.nq" }
],
"kinds": {
"concept": { "label": "Concept", "color": "#79c0ff", "shape": "round-octagon" }
}
}In this mode:
config.jsonstill supplies viewer metadata and node kind styling- the graph itself is imported from RDF
graphSourcescan merge instance RDF with ontology RDF at runtime
[
{
"id": "my-tour",
"title": "Guided Tour",
"description": "Walk through the key concepts.",
"file": "data/tutorials/my-tour.json"
}
]{
"id": "my-tour",
"title": "Guided Tour",
"description": "Walk through the key concepts.",
"stops": [
{
"node": "unique-id",
"depth": 1,
"title": "Stop Title",
"narrative": "Narrative text. Use [link text](node:node-id) for graph links and [link text](https://url) for external links.\n\nParagraphs separated by double newlines."
}
]
}Views filter the graph into topic-specific subgraphs. Each view selects edges by triple and includes its own tours.
{
"name": "My Topic",
"description": "A focused lens on this topic.",
"edges": [
["node-a", "node-b", "relates to"],
["node-c", "node-d", "depends on"]
],
"tours": [
{
"id": "intro",
"title": "Introduction",
"description": "Walk through the basics.",
"stops": [
{ "node": "node-a", "depth": 1, "title": "Start Here", "narrative": "..." }
]
}
]
}A data/views/index.json listing available views must also be committed:
[
{ "name": "My Topic", "description": "...", "file": "my-topic.json" }
]If no views are defined, the full graph is shown with tutorials from data/tutorials/.
ellipse, round-rectangle, diamond, round-hexagon, rectangle, round-octagon, barrel, round-pentagon, triangle, star
Create a repo with just a data/ directory and this workflow:
# .github/workflows/pages.yml
name: Deploy
on:
workflow_dispatch:
push:
branches: [main]
permissions:
pages: write
id-token: write
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: lambdasistemi/graph-browser/validate-action@main
- uses: lambdasistemi/graph-browser/build-action@main
- uses: actions/upload-pages-artifact@v4
with:
path: site
- id: deployment
uses: actions/deploy-pages@v5No build tools needed — the actions download the app and assemble the site.
Visit https://lambdasistemi.github.io/graph-browser/?repo=owner/repo to browse any repo with a data/ directory.
# In your flake.nix
inputs.graph-browser.url = "github:lambdasistemi/graph-browser";
# Use the lib output (viewer only, no repo management)
packages.default = graph-browser.packages.${system}.lib;Add .graph-browser.json to your repo root to customize data paths:
{
"config": "data/config.json",
"graph": "data/rdf/graph.ttl",
"tutorials": "data/tutorials/index.json"
}Without a manifest, the app looks for data/ on the repo's main branch via raw GitHub URLs.
nix develop -c just ci # lint + build + bundle
nix develop -c just export-rdf # regenerate data/rdf from the graph sources declared in data/config.json
nix develop -c just publish-vocab # generate /vocab/... namespace pages from ontology Turtle
nix develop -c just validate-rdf # validate RDF artifacts with SHACL
nix develop -c just build-docs # build docs, copy RDF artifacts, and publish /vocab/... pages into dist
nix develop -c just serve # serve example on port 10002
nix develop -c just dev # watch mode
nix develop -c just bundle-app # bundle app (with repo panel)
nix develop -c just bundle-lib # bundle lib (viewer only)
nix build .#app # nix build app output
nix build .#lib # nix build lib outputjust export-rdf runs the PureScript export entrypoint Rdf.Export.Main, which reconstructs the graph model from the configured graph sources and emits the derived RDF artifacts. The low-level triple storage and serialization is delegated through the thin Oxigraph FFI layer in src/FFI/Oxigraph.js.
The command writes:
data/rdf/graph.ttldata/rdf/graph.nqdata/rdf/core-ontology.ttldata/rdf/application-ontology.ttldata/rdf/core-ontology.mmddata/rdf/application-ontology.mmddata/rdf/shapes.ttldata/rdf/application-shapes.ttl
core-ontology.ttl is the shared graph-browser ontology. application-ontology.ttl is the repo-specific extension generated from local kinds, groups, and edge labels. core-ontology.mmd and application-ontology.mmd are generated Mermaid views of the same structures for lightweight visualization and Pages publishing.
just publish-vocab reads the ontology Turtle artifacts and generates human-browsable namespace pages under:
dist/vocab/termsdist/vocab/kindsdist/vocab/groupsdist/vocab/edges
Those pages are generated automatically from Turtle during the docs/site build. They are not maintained as a separate hardcoded term catalog.
This matters because ontology IRIs like https://lambdasistemi.github.io/graph-browser/vocab/terms#Node rely on the namespace document https://lambdasistemi.github.io/graph-browser/vocab/terms being published. The #Node fragment is client-side only.
Downstream repos can use the same Turtle-driven generator through the reusable action:
- uses: lambdasistemi/graph-browser/vocab-publish-action@main
with:
sources: data/rdf/core-ontology.ttl,data/rdf/application-ontology.ttl
output-dir: site
site-base-path: /your-repo-namejust validate-rdf runs two SHACL checks:
graph.ttlagainstshapes.ttlfor shared graph-browser instance structureapplication-ontology.ttlagainstapplication-shapes.ttlfor application vocabulary compatibility with the core ontology
That gives downstream applications an explicit contract: they are free to define their own ontology terms, but kinds must still extend gb:Node, groups must still use gb:Group, and application predicates must still refine gb:EdgeRelation.
Validate your data against the schemas in schema/:
config.schema.json— configurationtutorial.schema.json— guided tourtutorial-index.schema.json— tour listview.schema.json— view (subgraph lens with tours)manifest.schema.json—.graph-browser.jsonmanifest
Graph-browser publishes a reusable GitHub Action that validates your data against all schemas, checks edge integrity, kind references, duplicate IDs, and tutorial node references. Add it as a step in your workflow:
- uses: lambdasistemi/graph-browser/validate-action@main
with:
data-dir: data # optional, default: data
schema-ref: main # optional, pin to tag/shaSee GENERATE.md for prompt templates to generate graph data, tutorials, and configuration using Claude, ChatGPT, or any AI assistant with web access. The prompts are designed to produce valid JSON matching the schemas above.
- PureScript + Halogen — typed functional UI
- Cytoscape.js + fCoSE — graph visualization
- Nix flake — reproducible dev environment
- mkSpagoDerivation — sandboxed Nix build
- Spago — PureScript build
- Cardano Governance Graph — interactive knowledge graph of Cardano's on-chain governance
- Local LLM Graph — local LLM ecosystem: models, engines, quantization, hybrid cloud/local setups