Graphlens
Polyglot code-analysis framework — parses Python, TypeScript, Go, Rust & PHP into a shared graph IR (tree-sitter + type-aware resolvers: ty, tsc, gopls, rust-analyzer). Call/dependency graphs, cross-language boundaries, Neo4j export
Install / Use
npx skills add Neko1313/graphlensInstalls into whichever agent you are using.
Quality Score
Category
Development & EngineeringSupported Platforms
README
<div align="center"> <h1>graphlens</h1> <p>Extensible polyglot code analysis framework that parses source projects, normalizes their structure into a shared graph IR, and exposes it for dependency analysis, navigation, and code intelligence tooling.</p>[!IMPORTANT] graphlens is archived and no longer maintained. Its successor is callix.
callix is a full rewrite of this project by the same author, with the analysis moved to Rust. What it changes:
- One install, no assembly. graphlens asks you to bring the language servers yourself —
ty,gopls,rust-analyzer,intelephense— and to keep them onPATHand in step with each other. callix links the Python and TypeScript type checkers into the module, standard-library stubs included, sopip install callixis the whole setup. Go and Rust still use the toolchain your project already has, but no separate language server.- Faster. 5.2× on apache/superset, 3.3× on colinhacks/zod, 2.6× on gin-gonic/gin. The resolution phase in particular, which used to be JSON-RPC round-trips, dropped from 39.1s to 8.9s on superset.
- Lighter. Resolving Rust no longer keeps an interactive
rust-analyzerserver resident — a batch SCIP index is written once and read statically, instead of a process that grows into tens of gigabytes on a large workspace.- Same graph. The same 14 node kinds, 12 relation kinds, deterministic IDs and serialization format: a graph written here reads there and back. Structural parity is verified by diffing both implementations on superset, zod, gin, ripgrep and ruff.
Not carried over: the CLI, the MCP server, the Neo4j backend, the HTML visualization, and the PHP and C# adapters. If you depend on those, this repository stays readable at its final state.
Documentation · Repository · Issues
</div>Architecture
Repository → Language Adapter → GraphLens (IR) → Graph Backend
| Layer | Responsibility |
|---|---|
| Language Adapter | Parses source files, produces GraphLens |
| GraphLens | Typed nodes + directed relations (the IR) |
| Graph Backend | Persists or queries the graph (Neo4j, in-memory, …) |
Adapters are pure data producers — they never write to any backend. The graph is the only output.
Why graph IR?
- Language-agnostic — one shared model for Python, TypeScript, Go, Rust, PHP, C#, …
- Plugin-based adapters — each language is a separate package, registered via Python entry points
- Tree-sitter powered — all adapters use tree-sitter for CST parsing and exact span positions, combined with type-aware resolution (ty for Python, TypeScript Compiler API for TypeScript, gopls for Go, rust-analyzer for Rust, Intelephense for PHP, scip-dotnet for C#)
- Cross-language aware — adapters emit language-agnostic
BOUNDARYports (HTTP, queues, gRPC, Temporal);graphlens-linkconnects a consumer in one language to a provider in another - Monorepo aware —
can_handle()andfind_*_roots()handle multi-language repos correctly - Deterministic node IDs — SHA-256 hash of
project::kind::qualified_name→ stable across re-scans
Benchmarks
Analysis throughput on large real-world projects, refreshed automatically on
every release — one cold run per project inside the published Docker image
(so the numbers reflect exactly the toolchain users get). See
benchmarks/ to reproduce locally or add a project.
Last run: 2026-07-24 12:52 UTC · image latest · runner Linux x86_64 · single cold run, indicative only.
| Project | Lang | Commit | LOC | Files | Nodes | Relations | Time | Peak RSS | KLOC/s | Resolver | Resolved |
|---|---|---|--:|--:|--:|--:|--:|--:|--:|:--|--:|
| apache/superset | python | c83fb2b | 399 519 | 1 886 | 156 044 | 379 553 | 150.9s | 1,793 MB | 2.6 | ok | 84% of 281 667 (74s) |
| colinhacks/zod | typescript | 1fb56a5 | 74 194 | 404 | 8 623 | 24 557 | 22.2s | 567 MB | 3.3 | ok | 87% of 15 771 (19s) |
| gin-gonic/gin | go | 73726dc | 23 672 | 98 | 7 227 | 11 882 | 13.9s | 2,186 MB | 1.7 | ok | 100% of 8 920 (13s) |
| casdoor/casdoor | go | 696bcf0 | 86 898 | 458 | 14 987 | 28 276 | 130.1s | 14,503 MB | 0.7 | ok | 100% of 19 421 (127s) |
| gohugoio/hugo | go | 4d22555 | 224 821 | 897 | 34 809 | 72 225 | 110.8s | 9,499 MB | 2.0 | ok | 99% of 49 013 (104s) |
| BurntSushi/ripgrep | rust | 4649aa9 | 50 275 | 98 | 5 365 | 15 087 | 13.9s | 1,264 MB | 3.6 | ok | 99% of 11 435 (0s) |
| tokio-rs/axum | rust | c59208c | 43 653 | 296 | 8 093 | 14 798 | 70.2s | 4,544 MB | 0.6 | ok | 88% of 9 662 (0s) |
| astral-sh/ruff | rust | 6686f63 | 687 409 | 1 870 | 69 708 | 217 127 | 174.3s | 8,094 MB | 3.9 | ok | 100% of 155 276 (7s) |
| laravel/framework | php | bd8aeb6 | 441 358 | 2 478 | 139 764 | 189 708 | 113.9s | 2,958 MB | 3.9 | ok | 56% of 191 435 (98s) |
| dotnet/eShop | csharp | 9b4f943 | 25 385 | 527 | 13 124 | 29 171 | 26.0s | 2,413 MB | 1.0 | ok | 80% of 26 629 (2s) |
| microsoft/reverse-proxy | csharp | 4154b6d | 63 236 | 585 | 9 714 | 17 756 | 6.7s | 77 MB | 9.5 | unavailable | 0% of 72 295 (5s) |
| Total | | | 2 120 420 | | 467 458 | | 832.8s | | 2.5 | | 75% of 841 524 |
ℹ️ prepare exited 155 (dotnet restore YARP.sln)
<sub>Peak RSS measured via cgroup.v2 (whole process tree, incl. LSP resolver subprocesses). KLOC/s = analysed thousands-of-lines per second. Generated by benchmarks/run_benchmarks.py.</sub>
Documentation
Full product documentation lives at https://Neko1313.github.io/graphlens/
(built with Docusaurus from website/):
- Getting Started — install, quick start, core concepts
- Guides — library API, CLI, querying, visualization, Neo4j, cross-language
- CI Integration — strict mode, GitHub Actions, Docker, local hooks
- Adapters — Python, TypeScript, Go, Rust, PHP, C#, and writing your own
- Graph Model — nodes, relations, boundaries, serialization
- API Reference — exact signatures
To run the docs locally: cd website && pnpm install && pnpm start.
Installation
# Core library only (models, contracts, registry)
pip install graphlens
# Core + Python adapter
pip install "graphlens[python]"
# Core + TypeScript adapter
pip install "graphlens[typescript]"
# Core + Go / Rust / PHP / C# adapters
pip install "graphlens[go]"
pip install "graphlens[rust]"
pip install "graphlens[php]"
pip install "graphlens[csharp]"
# CLI (graphlens analyze / visualize / query / neo4j)
pip install "graphlens-cli[python]" # with Python adapter
pip install "graphlens-cli[all]" # Python + TS + Go + Rust + PHP + C# + Neo4j
With uv:
uv add graphlens
uv add "graphlens[python]"
uv add "graphlens[typescript]"
uv add "graphlens-cli[all]"
Docker (all adapters + toolchains pre-installed)
For CI, the published image bundles the CLI with every adapter and the
toolchains their resolvers drive (ty, Node, Go + gopls, Rust + rust-analyzer,
PHP + Intelephense) — no local setup required, and the supported way to get the
Go, Rust and PHP adapters (which are not published to PyPI). Mount your project
at /workspace:
docker run --rm -v "$PWD:/workspace" ghcr.io/neko1313/graphlens \
analyze /workspace --output /workspace/graph.json
The image is published to the GitHub Container Registry on each release
(:latest plus :X.Y.Z / :X.Y version tags).
Quick start
from pathlib import Path
from graphlens import adapter_registry
# Load and instantiate the Python adapter
adapter = adapter_registry.load("python")()
# Analyze a project — returns a GraphLens
graph = adapter.analyze(Path("./my-project"))
print(f"Nodes: {len(graph.nodes)}")
print(f"Relations: {len(graph.relations)}")
# Inspect nodes by kind
from graphlens import NodeKind
modules = [n for n in graph.nodes.values() if n.kind == NodeKind.MODULE]
classes = [n for n in graph.nodes.values() if n.kind == NodeKind.CLASS]
# Check the resolver actually ran (don't trust a silently degraded graph)
from graphlens import RESOLVER_STATUS_KEY
assert graph.metadata[RESOLVER_STATUS_KEY] == "ok"
# Query the graph (indexed lookups, no manual scanning)
fn = next(n fo
Related Skills
clawhub
385.5kSearch ClawHub for skills when a requested capability is not already available; install, verify, update, uninstall, publish, or sync skills.
coding-agent
385.5kDelegate coding work to Codex, Claude Code, or OpenCode as background workers; not simple edits or read-only code lookup.
node-connect
385.5kDiagnose OpenClaw Android, iOS, or macOS node pairing, QR/setup code, route, auth, and connection failures.
python-debugpy
385.5kDebug Python with pdb, breakpoint(), post-mortem inspection, and debugpy remote attach.
