callix
Polyglot code analysis in Rust. Parses Python, TypeScript, Go, Rust, PHP, C, C++ and YAML into a shared graph IR — with the type checkers linked in, so there are no language servers to install.
Repository → Language Adapter → Graph (IR) → your code
Nodes and directed relations, typed and deterministic: functions, classes, modules, the calls between them, and the HTTP or gRPC boundaries where one service meets another.
Why
Code analysis usually asks you to assemble it — install a language server, put
it on PATH, wire up the transport, keep the versions in step. callix links
the analysis engines into the module instead:
| Language | Symbol resolution | Extra setup |
|---|---|---|
| Python | ty, linked as a library | none |
| TypeScript | typescript-go, linked as a Go c-archive | none |
| Go | go/packages + go/types, same c-archive |
a Go toolchain |
| Rust | rust-analyzer scip index, decoded natively |
rust-analyzer and Cargo |
| PHP | a symbol table built from the sources | none |
| C / C++ | a symbol table over the parsed sources | none |
| YAML | none — it declares no symbols | none |
Python and TypeScript need nothing beyond the wheel — the checkers and their
standard-library stubs are inside it. Go and Rust use the toolchain the project
already has, because a standard library shipped as sources cannot be frozen
into a wheel. PHP and the C family have no checker worth linking and no widely
installed indexer worth shelling out to — every precise C/C++ option requires a
compile_commands.json, which almost no repository ships — so callix builds a
symbol table from the sources and reports degraded, honest about being a symbol
table and not a type checker.
Installation
pip install callix
Python ≥ 3.10. Wheels for Linux glibc and musl (x86_64, aarch64) and macOS (arm64, x86_64); Windows is not supported.
Usage
from callix import NodeKind, PythonAdapter
graph = PythonAdapter().analyze("path/to/project")
print(len(graph.nodes), len(graph.relations))
for node in graph.nodes_by_kind(NodeKind.FUNCTION):
print(node.qualified_name, graph.callers(node.id))
graph.to_json(indent=2) # serialization
old.diff(new) # structural diff
The same call works for every other language — TypeScriptAdapter, GoAdapter,
RustAdapter, PhpAdapter, CAdapter, CppAdapter, YamlAdapter — and each
discovers its own project roots, so a monorepo works without configuration.
Symbol resolution is on by default. resolve=False gives a structural graph;
graph.metadata["resolver_status"] always says how complete the result is.
A Python server declaring @app.get("/users/{id}") and a TypeScript client
calling fetch("/users/1") produce the same boundary node, so merging
their graphs links the two services. See
Cross-language analysis.
Command line and Docker
The same analysis without writing Python — and the formats other tools read:
docker run --rm -v "$PWD:/workspace" ghcr.io/callix-tools/callix:full \
export . -f lsif -o dump.lsif # GitLab code navigation, Sourcegraph-style tools
callix export also writes SCIP, CycloneDX, CSV, Graphviz and Mermaid; callix report
prints summaries, resolver status, dependencies, boundaries and call lists. The
full image carries the Go and Rust toolchains, so every language that has a
real resolver gets it. See
Command line,
Export formats and
Docker.
Documentation
https://callix-tools.github.io/callix/
- Installation · Quick start · Concepts
- Adapters and how the resolvers work
- Graph model · API reference
- Migrating from graphlens
Benchmarks
Last run: 2026-07-30 12:01 UTC · callix main · 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 | 181 320 | 370 764 | 19.4s | 1,026 MB | 20.6 | ok | 85% of 281 667 (11s) |
| colinhacks/zod | typescript | 1fb56a5 |
74 194 | 404 | 15 332 | 27 334 | 2.5s | 419 MB | 30.2 | ok | 89% of 17 067 (1s) |
| gin-gonic/gin | go | 73726dc |
23 374 | 97 | 13 109 | 19 424 | 6.1s | 948 MB | 3.8 | ok | 100% of 13 916 (1s) |
| casdoor/casdoor | go | 696bcf0 |
86 898 | 458 | 33 324 | 58 107 | 35.7s | 4,240 MB | 2.4 | ok | 100% of 36 633 (10s) |
| gohugoio/hugo | go | 4d22555 |
224 821 | 897 | 75 036 | 130 508 | 22.0s | 4,559 MB | 10.2 | ok | 98% of 87 043 (6s) |
| BurntSushi/ripgrep | rust | 4649aa9 |
50 275 | 98 | 7 787 | 22 852 | 12.8s | 1,077 MB | 3.9 | ok | 99% of 16 156 (0s) |
| tokio-rs/axum | rust | c59208c |
43 653 | 296 | 10 627 | 21 118 | 69.0s | 3,123 MB | 0.6 | ok | 87% of 12 625 (0s) |
| astral-sh/ruff | rust | 6686f63 |
687 409 | 1 870 | 102 595 | 330 597 | 176.0s | 6,007 MB | 3.9 | ok | 100% of 216 936 (2s) |
| laravel/framework | php | 92a7072 |
540 800 | 3 016 | 83 164 | 291 129 | 17.8s | 376 MB | 30.4 | degraded | 70% of 283 108 (1s) |
| redis/redis | c | 5279a8d |
374 211 | 786 | 156 896 | 200 372 | 7.0s | 294 MB | 53.8 | degraded | 100% of 161 477 (0s) |
| google/leveldb | cpp | 99b3c03 |
28 280 | 131 | 12 235 | 20 600 | 0.9s | 77 MB | 32.5 | degraded | 100% of 14 322 (0s) |
| facebook/rocksdb | cpp | 3b44608 |
774 485 | 1 342 | 300 996 | 513 211 | 26.9s | 718 MB | 28.8 | degraded | 100% of 433 814 (0s) |
| APIs-guru/openapi-directory | yaml | 959d727 |
1 268 530 | 971 | 11 812 | 16 795 | 5.8s | 115 MB | 219.8 | ok | — |
| argoproj/argo-cd | yaml | 564b949 |
322 262 | 2 201 | 2 220 | 2 246 | 1.4s | 91 MB | 222.5 | ok | — |
| Total | 4 898 711 | 1 006 453 | 403.3s | 12.1 | 91% of 1 574 764 |
Peak RSS measured via getrusage.max (largest single process — ours or a resolver subprocess; no cgroup counter was readable, so this is not the tree total). KLOC/s = analysed thousands-of-lines per second. Generated by benchmarks/run_benchmarks.py.
Speed-ups against graphlens, the Python implementation this replaces: 5.2× on apache/superset, 3.3× on colinhacks/zod, 2.6× on gin-gonic/gin. Details and method in Benchmarks.
Versioning
Semver covers the graph contract — the node and relation kinds, the two id
formulas, 1-based spans, node ordering, the serialization format — and the
Python API as generated into the committed .pyi. It does not cover what the
resolvers answer: the Python one is a pinned 0.0.x release of ty, the Rust
one is whatever rust-analyzer the machine has. A patch release may change
which CALLS edges appear. What is watched instead is the aggregate share of
resolved queries, recorded per project in the baselines.
Full statement, including which changes need a major release: Versioning.
Contributing
See CONTRIBUTING.md for the development loop, the build constraints, and how releases are cut.
License
MIT
Metadata
Release files for callix 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| callix-1.2.0.tar.gz | 934.8 kB | Without provenance | Details for callix-1.2.0.tar.gz |
Built distributions (wheels)
| File | Actions Reset | |||
|---|---|---|---|---|
| callix-1.2.0-cp310-abi3-musllinux_1_2_x86_64.whl | CPython 3.10 | abi3 | Linux musl 1.2+ x86-64 | Details for callix-1.2.0-cp310-abi3-musllinux_1_2_x86_64.whl |
| callix-1.2.0-cp310-abi3-musllinux_1_2_aarch64.whl | CPython 3.10 | abi3 | Linux musl 1.2+ ARM64 | Details for callix-1.2.0-cp310-abi3-musllinux_1_2_aarch64.whl |
| callix-1.2.0-cp310-abi3-manylinux_2_28_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ x86-64 | Details for callix-1.2.0-cp310-abi3-manylinux_2_28_x86_64.whl |
| callix-1.2.0-cp310-abi3-manylinux_2_28_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ ARM64 | Details for callix-1.2.0-cp310-abi3-manylinux_2_28_aarch64.whl |
| callix-1.2.0-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details for callix-1.2.0-cp310-abi3-macosx_11_0_arm64.whl |
| callix-1.2.0-cp310-abi3-macosx_10_12_x86_64.whl | CPython 3.10 | abi3 | macOS 10.12+ x86-64 | Details for callix-1.2.0-cp310-abi3-macosx_10_12_x86_64.whl |
Total release size: 117.8 MB
Release files / callix-1.2.0.tar.gz
| Download URL | callix-1.2.0.tar.gz |
|---|---|
| Size | 934.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
61b2b27ac31bf37c64da40cdfcc01879b5d23aa7bbddb1ded45d3ddc363734e5
|
|
BLAKE2b-256 checksum How to use checksums |
13d7d46a2012790c77b58ec9827daaf6d14f9830c6f1e55807093a2a76517c41
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / callix-1.2.0-cp310-abi3-musllinux_1_2_x86_64.whl
| Download URL | callix-1.2.0-cp310-abi3-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 20.5 MB |
| Tags | CPython 3.10 Linux musl 1.2+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
9dfc80838414873bd1a9e3bf178e76829f338c776708a3cf528a7f561130cc1c
|
|
BLAKE2b-256 checksum How to use checksums |
ddcc81fbfe23fbef9e7cbd4b38a1623673f6e9cd3d098a24e5d211aa11faaac9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / callix-1.2.0-cp310-abi3-musllinux_1_2_aarch64.whl
| Download URL | callix-1.2.0-cp310-abi3-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 19.2 MB |
| Tags | CPython 3.10 Linux musl 1.2+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
b734f3a007185a2da4e2b7cbb0ca70d0faf243c265b35fdc2da6c4d077e19a4d
|
|
BLAKE2b-256 checksum How to use checksums |
9b57d6ff9d97c0c40053227a19e5846cf6c1683ccfc5b5237154407ae5bd4117
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / callix-1.2.0-cp310-abi3-manylinux_2_28_x86_64.whl
| Download URL | callix-1.2.0-cp310-abi3-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 20.1 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
4954d5548ca896b8e3df200bca389404ce1b0d92fee8507598244b450433c325
|
|
BLAKE2b-256 checksum How to use checksums |
28990a0f1a11b22b0a3ed6d61564e975b057383a05743834348add610ab81125
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / callix-1.2.0-cp310-abi3-manylinux_2_28_aarch64.whl
| Download URL | callix-1.2.0-cp310-abi3-manylinux_2_28_aarch64.whl |
|---|---|
| Size | 19.0 MB |
| Tags | CPython 3.10 Linux glibc 2.28+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
b4118b350a7a62bc8c47ab3e21f56b8e7d067e3ff7fc08e442265ed4346d3d61
|
|
BLAKE2b-256 checksum How to use checksums |
24649ddf4309cbefc4a498c5d2c515547e673aebee915c51dbdf58d62e7d36c7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / callix-1.2.0-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | callix-1.2.0-cp310-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 18.6 MB |
| Tags | CPython 3.10 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
c32cdc77abe44af7ef8887fc0969a4d161c273444b7520561214dfe1d2603966
|
|
BLAKE2b-256 checksum How to use checksums |
cc5070240d5109e4c3633ada74925d4ce9c7160770a90d448add2c40f09d5fe5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / callix-1.2.0-cp310-abi3-macosx_10_12_x86_64.whl
| Download URL | callix-1.2.0-cp310-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 19.4 MB |
| Tags | CPython 3.10 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
12cbc187395f44f1f74d9420f209f9b48c660936611f5a2a09f1eb674e4844e9
|
|
BLAKE2b-256 checksum How to use checksums |
76df364813cdef88f95a5f10b5a3db26fd292cb1bf75237c5cf6e60da082915d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.13.5 {"installer":{"name":"uv","version":"0.13.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for callix 1.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.