An online platform to store, discover, and explore ShExMaps — mappings between RDF shapes defined by ShEx (Shape Expressions).
![]() |
![]() |
- REST API (
/api/v1/) with OpenAPI documentation at/api/v1/docs - SPARQL 1.1 endpoint (
/sparql) backed by QLever - React web interface — browse, search, create, and visualise ShExMaps
- ShExMap editor — create or edit a ShExMap with a Monaco ShEx editor, inline Turtle sample data, focus IRI, and live ShEx/RDF/full validation
- Pairing editor — side-by-side ShEx authoring with per-side validation, shared variable highlighting, and paired validate/materialise
- Optional authentication — OAuth2/OIDC (GitHub, ORCID, Google) + API keys; disabled by default
- Docker images published to GitHub Container Registry on every push to
master
git clone <repo>
cd shexmap-repository
cp .env.example .env # review and edit as needed
docker compose up --build -dOpen http://localhost.
- REST API docs: http://localhost/api/v1/docs
- SPARQL endpoint: http://localhost/sparql
- Backend: Node.js + Fastify (TypeScript)
- Triplestore: QLever
- Frontend: React + Vite + Tailwind CSS
- Visualisation: ReactFlow, Recharts
- Deployment: Docker + Docker Compose
QLever must be running locally before starting the API or frontend. Start it with Docker Compose (detached), then run the API and frontend dev servers:
# 1. Start QLever in the background (only needed once)
docker compose up qlever-init qlever -d
# 2. Set up the .env and symlink it for the API
cp .env.example .env # uses localhost:7001 for QLever
ln -s ../.env api/.env
# 3. API with hot reload
cd api && npm install && npm run dev
# 4. Frontend dev server (with HMR) — in a separate terminal
cd frontend && npm install && npm run devOpen http://localhost:5173.
The Vite dev server proxies /api → localhost:3000 and /sparql → localhost:7001.
All configuration is via environment variables. Copy .env.example to .env.
| Variable | Default | Description |
|---|---|---|
AUTH_ENABLED |
false |
Enable OAuth2/OIDC authentication |
QLEVER_SPARQL_URL |
http://localhost:7001/sparql |
QLever SPARQL endpoint |
JWT_SECRET |
(change this) | Secret for signing JWTs |
Navigate to /maps/new (or click + New Map in the nav bar).
- Fill in metadata — title (required), version, description, tags, source URL, and schema URL.
- Write ShEx content — use the Monaco ShEx editor with syntax highlighting.
- Add sample Turtle data — paste RDF in the Turtle editor below the ShEx editor. This is saved as the map's
sampleTurtleDataand also persisted to browser localStorage. - Validate — enter a focus IRI and click Validate to run ShEx/RDF/full validation inline before saving.
- Create Map — click Create Map to save. You are redirected to the new map's page, with Turtle data and focus IRI automatically restored.
To edit an existing map, navigate to /maps/<id>. The same editor and validation panel are available, plus version history and metadata editing.
Navigate to /pairings/create (or click Create Pairing in the nav).
- Select ShExMaps — pick a source and target ShExMap from the dropdowns, or create new ones inline. The latest saved version of each map is loaded automatically.
- Edit ShEx & sample data — each side has a Monaco ShEx editor and a Sample Turtle Data editor. Turtle data and the focus IRI are saved to browser localStorage per map and restored on next visit.
- Validate per side — click Validate in the Focus IRI row of either panel to check that the ShEx extracts bindings from the sample data. Results appear inline below the editor.
- Paired validation — use section 3 to validate across both sides. Choose a direction (Source→Target or Target→Source), then Validate to extract bindings or Validate & Materialise to also generate target RDF.
- Save — fill in the pairing metadata (title, tags, version, license) and click Save Pairing. On subsequent edits, an optional change note can be entered before clicking Update Pairing, which saves metadata and creates a version snapshot in one step. Use ↓ Download to export the pairing as JSON.
QLever stores all ShExMap data as RDF triples in an on-disk index. The index is built once at startup from Turtle files and updated at runtime via SPARQL UPDATE. Three scripts manage the lifecycle of this data.
The repository starts empty. To pre-populate with seed data, add Turtle files to sparql/seed/shexmaps/ and sparql/seed/pairings/ before the first run.
To rebuild the index from the current seed and ontology files (wipes all runtime data):
./scripts/rebuild-index.shThis stops QLever, wipes the data volume, copies the ontology and all seed Turtle files, rebuilds the index, and restarts QLever.
Dump the live triplestore to a Turtle file:
./scripts/backup-db.sh # writes to sparql/backup/YYYY-MM-DDTHH-MM-SS.ttl
./scripts/backup-db.sh my-backup.ttl # write to a specific fileRequires a running QLever instance. The script issues a CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o } query and saves the result as Turtle.
Rebuild the QLever index from a previously saved backup:
./scripts/restore-db.sh sparql/backup/2026-01-01T00-00-00.ttlThis stops QLever, rebuilds the index from the backup file, and restarts QLever. Destructive — the current index is wiped before restore. The script prompts for confirmation before proceeding.
Two GitHub Actions workflows build and publish Docker images to GitHub Container Registry (GHCR) on every push to master:
| Workflow | Trigger paths | Image |
|---|---|---|
build-api.yml |
api/**, docker/api/Dockerfile |
ghcr.io/<owner>/<repo>/api |
build-ui.yml |
frontend/**, docker/nginx/** |
ghcr.io/<owner>/<repo>/ui |
Each image is tagged with both latest and a YYYYMMDDHHmmss<sha> timestamp tag. Images are built for linux/amd64 and linux/arm64.
To pull the latest images:
docker pull ghcr.io/<owner>/<repo>/api:latest
docker pull ghcr.io/<owner>/<repo>/ui:latestApache 2.0






