A Zed editor extension and Rust LSP for the RDF family of languages — 11 languages covered end-to-end by a single language server.
Editor-only. This is a language tool: syntax, structure, and static lookups. No triple store, no SPARQL execution, no reasoning, no network.
- What you get
- Supported languages
- Feature matrix
- Screenshots
- Install from Zed
- Install from source
- Configuration
- Architecture
- Performance
- Verification discipline
- Publishing the extension to Zed
- Building
- Testing
- Project layout
- Contributing
- Roadmap
- Acknowledgements
- Licence
zed-rdf ships two pieces that work together:
rdf-lsp— a standalone Rust Language Server Protocol server that understands all 11 RDF-family languages. It runs anywhere an LSP client is supported (Zed, Neovim, VS Code with a generic LSP client, Helix…).- The Zed extension (
extensions/zed-rdf/) — a thin WASM launcher that wires up file extensions, tree-sitter grammars, and highlight queries, and startsrdf-lspwhen one of the supported file types is opened.
You can use the LSP independently of Zed. The Zed extension just gives you a one-click install.
| Language | Extensions | Highlight | Diagnostics | Hover | Completion | Format |
|---|---|---|---|---|---|---|
| Turtle | .ttl, .turtle |
✅ | ✅ | ✅ | ✅ | ✅ |
| TriG | .trig |
✅ | ✅ | ✅ | ✅ | ✅ |
| N-Triples | .nt |
✅ | ✅ | ✅ | ✅ | ✅ |
| N-Quads | .nq |
✅ | ✅ | ✅ | ✅ | ✅ |
| RDF/XML | .rdf |
✅ (XML) | ✅ | ✅ | ✅ | — |
| JSON-LD | .jsonld |
✅ (JSON) | ✅ | ✅ | ✅ | — |
| TriX | .trix |
✅ (XML) | ✅ | ✅ | ✅ | — |
| Notation3 (N3) | .n3 |
✅ | ✅ | ✅ | ✅ | — |
| SPARQL | .sparql, .rq, .ru |
✅ | ✅ | ✅ | ✅ | — |
| ShEx | .shex |
✅ | ✅ | ✅ | ✅ | — |
| Datalog | .dl |
✅ | ✅ | ✅ | ✅ | — |
Coverage: 149/149 W3C SPARQL 1.1 test-suite syntax entries pass. RDF/XML + JSON-LD syntax suites: 100 % green. NT, N-Quads, Turtle, TriG W3C manifests: 100 % green.
- Error-tolerant parsers — recovery at statement boundaries; a single typo in a Turtle file doesn't silence all downstream highlighting.
- Structured diagnostics — every error carries a stable code
(e.g.
SPARQL-BIND-001,SPARQL-PROLOGUE-001) keyed to the spec sections indocs/spec-readings/. - Adversary-hardened — each parser has been fuzzed against a shared hive of adversary fixtures (see Verification).
| Feature | Implementation notes |
|---|---|
| Diagnostics | Push model (publishDiagnostics); full-sync; one diagnostic per error with code. |
| Hover | Vocabulary lookup against 513 curated terms across 11 well-known vocabularies. |
| Completion | Per-language keyword lists + vocab-aware prefix expansion. |
| Goto definition | Turtle @prefix → IRI resolution; SPARQL variable → first binding site. |
| Document symbols | Hierarchical: prefixes, blank node scopes, rule heads. |
| Formatting | Deterministic pretty-printer for NT, N-Quads, Turtle, TriG (idempotent under re-run). |
| Rename | Turtle prefix labels (all <label>: occurrences); SPARQL variables (?var/$var). |
| Code actions | Sort prefixes, add missing prefix, extract prefix (13 well-known namespaces built in). |
| Semantic tokens | 9-type legend, delta-encoded. 562 µs for 10k-line Turtle (178× under the 100 ms gate). |
| Incremental parse | Parse cache with skip-on-no-change; statement-boundary-aware re-parse window. |
All with label + description for hover:
xsd, rdf, rdfs, owl, skos, sh (SHACL), dcterms, dcat,
foaf, schema (Schema.org), prov — 513 terms total.
- Tree-sitter-based syntax highlighting (grammars pinned by commit).
- File type associations, bracket matching, auto-indent, folding.
- Works with Zed's built-in formatter key binding (
Cmd-Shift-I).
Coming once the extension is live in the Zed registry. Preview locally with Install from source.
The extension is pending submission to the public registry. See Publishing the extension to Zed for status.
Once published:
- Open Zed.
Cmd-Shift-X(macOS) /Ctrl-Shift-X(Linux) → Extensions.- Search for rdf and click Install.
- Install
rdf-lspbinary (see Building) and ensure it's on yourPATH. The extension looks forrdf-lspviawhich rdf-lsp.
# Rust stable
rustup install stable
rustup default stable
# Zed extension WASM target
rustup target add wasm32-wasip2cd /path/to/zed-rdf
cargo install --path crates/rdf-lsp
# places `rdf-lsp` in ~/.cargo/bin (make sure it's on PATH)
rdf-lsp --version# From Zed:
# Cmd-Shift-P -> "zed: install dev extension" -> pick extensions/zed-rdf/Open any .ttl / .sparql / .shex / etc. file — you should see
highlighting immediately and diagnostics after a brief parse.
The extension needs no configuration out of the box. rdf-lsp is
launched by Zed when a supported file is opened.
To point at a specific binary (e.g. for development), set the language
server binary path in your Zed settings.json:
{
"lsp": {
"rdf-lsp": {
"binary": {
"path": "/absolute/path/to/rdf-lsp"
}
}
}
}┌───────────────────────────┐ ┌─────────────────────────────────┐
│ Zed editor │ │ rdf-lsp (standalone Rust binary)│
│ │ │ │
│ ┌─────────────────────┐ │ │ dispatch.rs (LSP glue) │
│ │ zed-rdf extension │ │ │ │ │
│ │ (WASM, cdylib) │◀─┼───┼──┤ hover / completion / … │
│ │ │ │ │ │ │
│ │ launches rdf-lsp │ │ │ 11 parsers (rdf-ntriples, │
│ │ via `which` │ │ │ rdf-turtle, rdf-xml, │
│ │ │ │ │ rdf-jsonld, rdf-trix, │
│ │ tree-sitter queries│ │ │ rdf-n3, sparql-syntax, │
│ │ (highlight only) │ │ │ shex-syntax, datalog-syntax) │
│ └─────────────────────┘ │ │ │
└───────────────────────────┘ └─────────────────────────────────┘
Full details in docs/sparc/03-architecture.md
and the ADRs under docs/adr/.
Benchmarked with criterion; see
crates/<parser>/benches/. Targets and measured results at v0.1.0:
| Metric | Measured | Target |
|---|---|---|
| N-Triples parse throughput | ≥ 200 MB/s | ≥ 200 MB/s |
| Turtle parse throughput | ≥ 80 MB/s | ≥ 80 MB/s |
| SPARQL parse throughput | ≥ 1000 q/s | ≥ 1000 q/s |
| Semantic-tokens on 10k-line Turtle | 562 µs | ≤ 100 ms |
CI fails on > 10 % regression against committed baselines
(bench/baselines/).
Every main parser is verified three ways (ADR-0019):
- Shadow parser — an independent implementation in a disjoint cohort (model-diverse, namespace-isolated from the main parser's memory). Diff-harnessed output must match canonical facts.
- Oracle adapter — third-party parsers (
oxttl,oxrdfxml,oxjsonld,spargebra,sophia) viardf-diff-oracles. - Adversary hive — a separate cohort authors failure-mode fixtures without access to implementation memory. At v0.1.0: 33 findings documented, 24 vetoes fired.
Plus:
- Fuzzing. Per-crate
cargo-fuzztargets with a 3-invariant contract (no panics, structured rejection shape, linear output bound). CI runs 60-second smoke on every PR and 30-minute nightly soak across 12 targets. - W3C conformance gates. 0 allow-list for NT/N-Quads/Turtle/TriG/SPARQL/ RDF-XML/JSON-LD.
The public Zed extension registry is at https://github.com/zed-industries/extensions. The flow (verified 2026-04-20):
- ✅ Repository has a permissive license at the root
(
LICENSE-APACHE/LICENSE-MIT— both accepted). - ✅
extension.tomlhas a stableid,name,version,description,authors, and a correctrepositoryURL. - ✅
extension.toml'szed_extension_apiversion pin is current. Verify against crates.io/zed_extension_api before submitting. - ✅ The host repo (
zed-rdf) is public on GitHub (see Publishing to a public repo below).
-
Tag your release. The
versionfield inextension.tomlmust match the state at a specific commit SHA.git tag -a v0.1.1 -m "zed-rdf v0.1.1" git push origin v0.1.0 -
Fork the registry to a personal GitHub account (not an org — staff need push access to your PR branch):
gh repo fork zed-industries/extensions --clone cd extensions -
Add this repo as a submodule under
extensions/zed-rdf/:git submodule add \ https://github.com/<your-user>/zed-rdf.git \ extensions/zed-rdf cd extensions/zed-rdf git checkout v0.1.1 # exact commit matching extension.toml version cd ../.. -
Add an entry to
extensions.toml(alphabetically sorted):[rdf] submodule = "extensions/rdf" version = "0.1.1" path = "extensions/zed-rdf" # subdir inside the submodule
The
pathkey is critical — this is a monorepo; the extension lives atextensions/zed-rdf/inside the outer repo. -
Sort and validate:
pnpm install # one-time pnpm sort-extensions -
Open a PR to
zed-industries/extensions. Zed CI will:- Validate the license.
- Validate the
extension.tomlschema. - Build your extension to WASM from source at the pinned commit.
- Run
dangerfile.tssort / metadata checks.
-
Wait for review and merge. Once merged, the extension appears in Zed's in-app Extensions UI within minutes (next registry refresh).
Same flow: bump version in both extension.toml here and extensions.toml
in your registry fork, point the submodule at the new commit SHA, open a PR.
cd /path/to/zed-rdf
gh repo create zed-rdf --public \
--description "Zed extension + Rust LSP for RDF, SPARQL, ShEx, Datalog" \
--source=. --remote=origin --push
git push --tags # so phase-i/done and v0.1.0 reach the remoteTemplate PRs to use as guidance (both recently merged monorepo-layout LSP-launching extensions):
- zed-industries/extensions#5494
— csskit-lsp (merged 2026-04-13). Monorepo with
pathkey. - zed-industries/extensions#5035 — rovo language server.
# All workspace crates
cargo build --workspace --release
# Just the LSP binary (for use outside Zed)
cargo install --path crates/rdf-lsp
# The Zed extension (produces WASM)
cd extensions/zed-rdf
cargo build --release --target wasm32-wasip2# Full workspace test suite
cargo test --workspace --all-features
# Clippy gate (used in CI)
cargo clippy --workspace --all-features -- -D warnings
# Dependency / license audit
cargo deny check
# W3C conformance sweep (requires vendored suites in external/tests/)
cargo run -p xtask -- verify
# Fuzz smoke (60 seconds per target; needs cargo-fuzz + nightly)
cd crates/rdf-ntriples/fuzz
cargo +nightly fuzz run parse_ntriples -- -max_total_time=60 -detect_leaks=0zed-rdf/
├── crates/ # all Rust crates
│ ├── rdf-diagnostics/ # shared diagnostic infrastructure
│ ├── rdf-iri/ # RFC 3987 IRI parser / RFC 3986 resolver
│ ├── rdf-ntriples/ # N-Triples 1.1 + N-Quads 1.1
│ ├── rdf-turtle/ # Turtle 1.1 + TriG 1.1
│ ├── rdf-xml/ # RDF/XML
│ ├── rdf-jsonld/ # JSON-LD 1.1 syntax + @context
│ ├── rdf-trix/ # TriX
│ ├── rdf-n3/ # Notation3
│ ├── sparql-syntax/ # SPARQL 1.1 query + update
│ ├── shex-syntax/ # ShEx compact syntax
│ ├── datalog-syntax/ # Datalog
│ ├── rdf-vocab/ # 513 terms across 11 vocabs
│ ├── rdf-format/ # pretty-printers
│ ├── rdf-lsp/ # the language server binary
│ ├── syntax/ # shadow parsers (verification only)
│ └── testing/ # rdf-diff harness + oracle adapters
├── extensions/
│ └── zed-rdf/ # WASM extension (cdylib)
├── docs/
│ ├── adr/ # 28 architecture decision records
│ ├── sparc/ # SPARC methodology phases 01-05
│ ├── spec-readings/ # annotated W3C spec pins
│ ├── runbooks/ # ops procedures
│ └── verification/ # adversary findings, vetoes
├── xtask/ # workspace task runner (W3C verify)
├── external/tests/ # vendored W3C test suites (subtree)
├── .github/workflows/ # CI: test, clippy, deny, fuzz, tree-sitter
├── CHANGELOG.md
├── CONTRIBUTING.md
└── README.md
See CONTRIBUTING.md. The short version:
- Open an issue first for anything larger than a typo.
- All code goes in via PR; two-reviewer rule for parser crates.
- CI must be green (
cargo test, clippy-D warnings,cargo deny, fuzz smoke, tree-sitter query parse). - New languages / features require an ADR under
docs/adr/.
Shipped in v0.1.0 — all 11 language parsers, full LSP, Zed extension scaffold, 100 % W3C conformance on the syntax gates.
Out of scope — intentionally. See
docs/sparc/01-specification.md §2:
no triple store, no query execution, no OWL/SHACL/ShEx validation, no
Datalog evaluation, no network I/O. The sign on the door.
Candidate for future work:
- RDF 1.2 syntax (triple terms) behind a feature flag — waiting on REC.
- JSON-LD 1.1 expand/compact (currently only
@contextwell-formedness). - Workspace symbols across files.
- Additional tree-sitter grammars for RDF/XML and JSON-LD (currently delegated to Zed's built-in XML/JSON grammars).
- W3C RDF and SPARQL working groups for the specs and test suites.
- Oxigraph for
oxttl,oxrdfxml,oxjsonld,spargebra— used as oracle parsers in our verification harness. - Sophia — also used as an oracle.
- The tree-sitter-turtle, tree-sitter-sparql, and tree-sitter-shex grammar authors.
- Zed for the editor and extension API.
Dual-licensed under Apache-2.0 OR MIT at your option. See
LICENSE-APACHE and LICENSE-MIT.
Contributions are accepted under the same terms — see
CONTRIBUTING.md.