cordx56/rustowl
Visualize Ownership and Lifetimes in Rust
Healthy across all four use cases
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2d ago
- ✓3 active contributors
- ✓MPL-2.0 licensed
Show all 7 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Small team — 3 contributors active in recent commits
- ⚠Concentrated ownership — top contributor handles 78% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/cordx56/rustowl)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/cordx56/rustowl on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: cordx56/rustowl
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/cordx56/rustowl shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across all four use cases
- Last commit 2d ago
- 3 active contributors
- MPL-2.0 licensed
- CI configured
- Tests present
- ⚠ Small team — 3 contributors active in recent commits
- ⚠ Concentrated ownership — top contributor handles 78% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live cordx56/rustowl
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/cordx56/rustowl.
What it runs against: a local clone of cordx56/rustowl — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in cordx56/rustowl | Confirms the artifact applies here, not a fork |
| 2 | License is still MPL-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 32 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of cordx56/rustowl. If you don't
# have one yet, run these first:
#
# git clone https://github.com/cordx56/rustowl.git
# cd rustowl
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of cordx56/rustowl and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "cordx56/rustowl(\\.git)?\\b" \\
&& ok "origin remote is cordx56/rustowl" \\
|| miss "origin remote is not cordx56/rustowl (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MPL-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MPL-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is MPL-2.0" \\
|| miss "license drift — was MPL-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "src/bin/core" \\
&& ok "src/bin/core" \\
|| miss "missing critical file: src/bin/core"
test -f "Cargo.toml" \\
&& ok "Cargo.toml" \\
|| miss "missing critical file: Cargo.toml"
test -f "lua/rustowl/init.lua" \\
&& ok "lua/rustowl/init.lua" \\
|| miss "missing critical file: lua/rustowl/init.lua"
test -f "lua/rustowl/lsp.lua" \\
&& ok "lua/rustowl/lsp.lua" \\
|| miss "missing critical file: lua/rustowl/lsp.lua"
test -f "build.rs" \\
&& ok "build.rs" \\
|| miss "missing critical file: build.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 32 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~2d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/cordx56/rustowl"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
RustOwl is an LSP-based visualization tool that analyzes Rust source code and displays ownership movement and variable lifetimes using color-coded underlines in editor hover tooltips. It solves the problem of understanding complex Rust borrow checker behavior by providing real-time graphical feedback on whether variables are definitely live, maybe live, borrowed immutably/mutably, moved, or in error states. Monorepo structure: core analysis engine in src/ (Rust with rustc_private integration), CLI via clap in src/main.rs, LSP server via tower-lsp, editor plugins in separate repos (vscode plugin at cordx56/rustowl-vscode, neovim/emacs via package managers). algo-tests/ contains algorithm validation. build.rs handles man page generation via clap_mangen.
👥Who it's for
Rust developers learning ownership semantics or debugging borrow checker errors; educators teaching Rust memory model; IDE/editor plugin maintainers (VS Code, Neovim, Emacs, JetBrains) who integrate RustOwl via LSP to help users understand lifetime violations and ownership flows.
🌱Maturity & risk
Actively maintained and approaching 1.0.0 (current version 1.0.0-rc.1). Has comprehensive CI/CD via GitHub Actions (build.yml, checks.yml, security.yml, release.yml), published on crates.io, AUR, WinGet, and VS Code Marketplace. Test suite exists (algo-tests/, benches/). However, release candidate status suggests some API or behavior refinement may still occur.
Moderate risk from rustc_private dependency (enabled in .cargo/config.toml) which ties RustOwl to specific Rust compiler versions and may break on rustc updates. Single maintainer (cordx56) visible in repo structure. Dependency chain includes tower-lsp, tokio, reqwest which are well-maintained but add complexity. No visible major issue backlog documented in file list, but LSP-based analysis is inherently complex.
Active areas of work
Approaching 1.0 release (version 1.0.0-rc.1). Active workflows for dependabot updates, changelog management via .chglog/, Docker builds, security scanning. Recent additions include Neovim and Emacs plugin support (suggested by .github/workflows/neovim-checks.yml, .luacheckrc). Changelog template at .chglog/CHANGELOG.tpl.md indicates structured release management.
🚀Get running
git clone https://github.com/cordx56/rustowl.git && cd rustowl && cargo build --release. Binary placed in target/release/rustowl. Requires Rust toolchain with rustc_private support (nightly or specific stable version). Test with: cargo test --all or cargo bench for benchmarks.
Daily commands: cargo run -- --help for CLI usage. For LSP server mode: cargo build --release, then configure your editor to invoke target/release/rustowl as an LSP server. VS Code users install the extension from Marketplace (cordx56.rustowl-vscode). Neovim/Emacs: follow plugin installation docs (not in main repo).
🗺️Map of the codebase
src/bin/core— Entry point for the rustowl CLI binary that drives ownership and lifetime visualization analysisCargo.toml— Project manifest defining all dependencies and build configuration for rustowl, including LSP and rustc_private usagelua/rustowl/init.lua— Neovim plugin initialization that integrates rustowl with the editor and coordinates LSP communicationlua/rustowl/lsp.lua— LSP client implementation for Neovim that handles server communication and response parsingbuild.rs— Build script that likely manages rustc_private dependencies and compilation configurationdocs/lsp-spec.md— Defines the LSP protocol specification and custom methods for ownership/lifetime visualization requestsrust-toolchain.toml— Locks Rust toolchain version critical for rustc_private API stability
🛠️How to make changes
Add a new LSP custom method for ownership visualization
- Define the custom LSP method signature and request/response types in the protocol specification (
docs/lsp-spec.md) - Implement the analysis logic in the Rust binary's core analyzer (
src/bin/core) - Add a handler in the LSP server to process the new method request (
src/bin/core) - Implement the client-side handler in the Neovim LSP module (
lua/rustowl/lsp.lua) - Add UI rendering logic if the method returns visual elements (
lua/rustowl/highlight.lua) - Add Lua tests to validate the full request/response cycle (
nvim-tests/test_lsp.lua)
Add support for a new editor integration
- Create editor-specific configuration documentation in the docs folder (
docs) - Implement or document the LSP client initialization for the target editor (
docs/lsp-spec.md) - Add editor-specific plugin/extension files following the editor's conventions (
lua/rustowl/lsp.lua) - Document installation steps and configuration in a new guide file (
docs/installation.md) - Update CI/CD workflows if cross-platform testing is needed (
.github/workflows/checks.yml)
Optimize analyzer performance for large codebases
- Create or extend performance benchmarks with new test case (
benches/rustowl_bench_simple.rs) - Profile and optimize the core analysis algorithm (
src/bin/core) - Add algorithm correctness tests to prevent regression (
algo-tests/src/lib.rs) - Document performance improvements and trade-offs in CHANGELOG (
CHANGELOG.md) - Run performance test suite to validate improvements (
perf-tests/dummy-package/benches/bench_target.rs)
Add visualization styling for new Rust language feature
- Define new highlight groups and color scheme in Neovim config (
lua/rustowl/highlight.lua) - Update the analyzer to detect and categorize the new language feature (
src/bin/core) - Add LSP response types for the new visualization data (
docs/lsp-spec.md) - Implement rendering logic in the Neovim plugin (
lua/rustowl/show-on-hover.lua) - Add test cases covering the new visualization feature (
nvim-tests/test_highlight.lua)
🔧Why these technologies
- rustc_private — Provides access to Rust compiler internals (MIR, borrow checker state) needed to analyze ownership and lifetimes at compile time
- LSP (Language Server Protocol) — Editor-agnostic protocol enabling single analyzer backend to serve multiple editors (Neovim, VS Code, Emacs) without duplication
- Lua (Neovim plugin) — Lua is Neovim's native plugin language, enabling tight integration with editor UI, keybindings, and highlight system
- Rust binary CLI — Core analyzer implemented in Rust for performance, memory safety, and direct rustc API access
⚖️Trade-offs already made
-
rustc_private for compiler internals vs. stable rustc APIs
- Why: Stable APIs do not expose MIR or borrow checker state needed for visualization; rustc_private provides required data
- Consequence: Requires pinning Rust toolchain version; breaks on rustc updates; must track rustc changes in maintenance
-
LSP server as single backend for multiple editors
- Why: Avoids reimplementing analyzer in each editor's plugin language; reduces code duplication and maintenance burden
- Consequence: LSP protocol communication overhead; slower than native plugins; requires editor-specific client plugins
-
Hover-based visualization vs. persistent sidebar panel
- Why: Hover requires minimal editor real estate and works across all editors; less intrusive to existing workflows
- Consequence: Visualization only appears on demand; cannot see multiple data points simultaneously; less discoverable
-
Offline analysis vs. real-time streaming
- Why: Compiler analysis is CPU-intensive and non-incremental; better to compute on-demand than block editor on every keystroke
- Consequence: Latency on first hover (50–200ms); not suitable for aggressive real-time features
🚫Non-goals (don't propose these)
- Does not replace rustc error messages; complements the compiler's diagnostics
- Not a real-time continuous analysis tool; analysis runs on user request (hover/command)
- Does not handle non-Rust code or polyglot projects; Rust-focused only
- Does not provide refactoring suggestions; visualization-only, no automated code transformation
- Does not work with stable Rust versions; requires nightly toolchain with rustc_private access
🪤Traps & gotchas
rustc_private dependency requires nightly Rust or exact stable rustc version match—changing Rust versions may break builds. LSP server mode may require specific environment variables for logging (check simple_logger configuration). Tree-sitter parser (tree-sitter-rust) may not handle all Rust syntax edge cases—check algo-tests for known limitations. .valgrind-suppressions present suggests memory profiling is done; not all test results may be deterministic. Docker builds require specific target configurations (see .github/workflows/docker-checks.yml).
🏗️Architecture
💡Concepts to learn
- Lifetime analysis via rustc_private — Core capability of RustOwl; understanding how rustc_private exposes internal compiler ASTs enables you to extend analysis to new Rust language features
- Language Server Protocol (LSP) — RustOwl is LSP-first; all editor integrations communicate via LSP hover responses, so understanding the protocol is essential for debugging editor integration issues
- Borrow checker and ownership semantics — The entire purpose of RustOwl is to visualize borrow checker behavior; deep knowledge of move semantics, borrowing rules, and lifetime bounds is required to understand what RustOwl displays
- Tree-sitter incremental parsing — RustOwl uses tree-sitter-rust for efficient syntax analysis; understanding incremental parsing enables optimization of real-time hover analysis performance
- Dataflow analysis (definitely live / maybe live) — RustOwl's green/blue/purple underlines represent dataflow states (definitely live vs maybe live); this is a form of abstract interpretation that tracks variable liveness across control flow paths
- Hover-driven LSP diagnostics — RustOwl transmits lifetime information via LSP hover responses rather than standalone diagnostics; this design choice affects how visualization data is structured and serialized
- Tokio async runtime and tower middleware — RustOwl's LSP server is built on tokio and tower-lsp; modifying the server architecture or adding concurrent analysis requires understanding Tokio's task model and tower's service abstraction
🔗Related repos
rust-lang/rust-analyzer— Shares rustc_private dependency and LSP foundation; RA's type inference could complement RustOwl's lifetime analysisWilfred/difftastic— Alternative Rust tooling that uses tree-sitter for deep AST understanding; similar architectural patterns for syntax-driven analysismun-lang/mun— Competing dynamic Rust dialect with its own ownership model visualization needs; shares audience of Rust memory model educationastexplorer/astexplorer— Generic AST visualization tool; RustOwl is domain-specific for Rust lifetimes but uses similar tree-sitter parsing approachtokio-rs/tokio— RustOwl is a heavy user of tokio for async LSP server implementation; understanding tokio is essential for modifying LSP server code
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add integration tests for LSP server functionality
The repo has comprehensive CI/CD workflows and LSP configuration files (tower-lsp 0.20 dependency, docs/lsp-spec.md), but there are no visible integration tests in the file structure. The algo-tests directory only contains algorithm tests for vec.rs. Adding LSP integration tests would ensure the language server protocol implementation works correctly across editor implementations (VS Code, Neovim, Emacs documented in docs/), preventing regressions in core functionality.
- [ ] Create tests/lsp_integration_tests.rs to test LSP server initialization, hover requests, and definition lookups
- [ ] Add test fixtures in tests/fixtures/ with sample Rust code for ownership/lifetime visualization
- [ ] Update .github/workflows/checks.yml to run integration tests (currently missing from visible workflows)
- [ ] Test against the documented editor configurations in docs/vscode-configuration.md, docs/neovim-configuration.md, and docs/emacs-configuration.md
Add benchmarks for tree-sitter parsing and ownership analysis
The repo already has a benchmark infrastructure (benches/rustowl_bench_simple.rs with Criterion), but only one benchmark file exists. Given that rustowl uses tree-sitter-rust (0.24) and performs ownership/lifetime analysis via rayon parallelization, adding comprehensive benchmarks would help maintain performance across releases and identify bottlenecks during optimization. This is critical for a visualization tool where latency impacts user experience.
- [ ] Expand benches/rustowl_bench_simple.rs to include benchmarks for tree-sitter parsing on various file sizes
- [ ] Add benchmarks measuring ownership graph construction time with rayon parallelization
- [ ] Create benchmarks for LSP request latency (hover, goto-definition) which directly affects editor responsiveness
- [ ] Document expected performance targets in docs/performance.md or CONTRIBUTING.md
Add documentation for build.rs and build-time configuration
The repo has a build.rs file but no documentation explaining its purpose or how to configure build-time features. The build script uses clap_mangen, clap_complete, and rustc_version, suggesting it generates man pages and shell completions. However, contributors won't understand how to extend or debug the build process. Adding build documentation would reduce contributor friction and ensure the shell completion generation works across platforms (Windows MSV, x86_64, aarch64).
- [ ] Create docs/build.md documenting what build.rs does (man page generation, completion generation, version detection)
- [ ] Document how to test build.rs locally with different Rust versions using rustc_version
- [ ] Add notes in docs/CONTRIBUTING.md linking to build.md and explaining shell completion workflows
- [ ] Add inline comments to build.rs explaining clap_mangen and clap_complete usage for maintainability
🌿Good first issues
- Add snapshot tests for complex ownership scenarios (e.g. nested borrows, closure captures) in algo-tests/src/lib.rs using the insta crate which is already a dev-dependency—currently only vec.rs has tests
- Document the LSP message protocol for visualization underlines in docs/ (e.g. which hover response field carries color codes, how purple/green/red are encoded)—currently only visual README exists, not protocol spec
- Add integration tests in algo-tests/ for editor plugin responses; verify that the LSP server correctly serializes lifetime data for VS Code/Neovim when hovering over specific code positions—tests exist but may lack editor-specific cases
⭐Top contributors
Click to expand
Top contributors
- @dependabot[bot] — 78 commits
- @cordx56 — 14 commits
- @MuntasirSZN — 8 commits
📝Recent commits
Click to expand
Recent commits
e89f3e8— feat: new lifetime visualization algorithm based on CFG analysis (#595) (cordx56)5e8fa29— build(deps): bump the version group in /vscode with 9 updates (#599) (dependabot[bot])7fa89d0— build(deps-dev): bump the version group in /scripts with 2 updates (#598) (dependabot[bot])9365def— build(deps): bump the version group with 2 updates (#597) (dependabot[bot])3d3e347— build(deps): bump crate-ci/typos from 1.45.1 to 1.46.0 (#596) (dependabot[bot])94bcfa6— build(deps-dev): bump the version group in /vscode with 7 updates (#594) (dependabot[bot])c7adbc3— build(deps): bump the version group with 6 updates (#593) (dependabot[bot])3c4d17b— build(deps-dev): bump @commitlint/cli in /scripts in the version group (#592) (dependabot[bot])d075468— build(deps): bump crate-ci/typos from 1.45.0 to 1.45.1 (#588) (dependabot[bot])9bfda73— build(deps): bump rand from 0.9.2 to 0.9.4 (#590) (dependabot[bot])
🔒Security observations
The rustowl project demonstrates reasonable security practices with use of maintained dependencies and CI/CD workflows. However, there are several concerns: (1) The Cargo.toml contains critical configuration errors (invalid edition, incomplete dependency) that prevent proper builds, (2) Docker containerization lacks non-root user enforcement, (3) Network-dependent operations (reqwest) should be regularly audited, and (4) The LSP server processing untrusted Rust code should implement
- High · Invalid Rust Edition in Cargo.toml —
Cargo.toml (line with edition specification). The Cargo.toml specifies edition = '2024', which is not a valid Rust edition. Valid editions are 2015, 2018, and 2021. This may cause build failures or unexpected behavior during compilation. Fix: Change edition to a valid value: '2021' (recommended for modern Rust projects) or '2018'. - High · Incomplete Dependency Declaration —
Cargo.toml (target-specific dependencies section). The tikv-jemalloc-sys dependency declaration appears truncated in the target-specific dependencies section. This incomplete configuration could cause build failures or unpredictable behavior. Fix: Complete the tikv-jemalloc-sys dependency declaration with proper version specification, e.g., 'version = "0.5"' and close the section properly. - Medium · Network Dependency Without Explicit Security Review —
Cargo.toml (reqwest dependency with 'socks' feature). The project uses 'reqwest' with SOCKS proxy support enabled. While reqwest is maintained, dependencies that handle network requests should be regularly audited for vulnerabilities. The SOCKS feature adds additional attack surface. Fix: Regularly run 'cargo audit' to check for known vulnerabilities. Consider if SOCKS proxy support is actually needed for the LSP use case. Review reqwest security advisories periodically. - Medium · Docker Multi-stage Build Without Non-root User —
Dockerfile (final stage). The final Docker image runs processes as root user by default. This violates the principle of least privilege and increases the impact of any potential container escape or compromise. Fix: Add a non-root user to the final stage: Create a dedicated user (e.g., 'rustowl') with minimal permissions and switch to it using USER directive before setting the entrypoint. - Medium · Incomplete RustOwl Invocation in Dockerfile —
Dockerfile (final RUN instruction). The final line 'RUN rustowl' appears incomplete and will cause the Docker build to fail. This suggests incomplete or untested configuration. Fix: Either remove this incomplete command or complete it with proper arguments (e.g., 'RUN rustowl --version' for verification) or use it as a health check. - Low · Outdated Debian Base Image References —
Dockerfile (FROM debian:bookworm-slim and apt-get install commands). The Dockerfile uses pinned Debian packages from bookworm with specific CVE-addressed versions (e.g., ca-certificates=20230311+deb12u1), but these pins may become stale over time. Fix: Implement a process to regularly rebuild Docker images to incorporate latest security patches. Consider using more recent Debian versions or implementing automated dependency updates. - Low · LSP Server May Handle Untrusted Input —
Cargo.toml (tower-lsp and tree-sitter dependencies), project implementation. The project implements an LSP server (tower-lsp) that processes arbitrary Rust code. While tree-sitter is used for parsing, any parser-based tool should be aware of potential DoS attacks via maliciously crafted input. Fix: Implement timeout mechanisms for parsing operations. Add resource limits for large files. Consider fuzzing the parser with malformed inputs during development. - Low · Metadata URL Uses HTTP Without HTTPS Enforcement —
Cargo.toml (cargo_metadata dependency). The cargo_metadata dependency fetches Rust metadata. Ensure all metadata sources use HTTPS to prevent man-in-the-middle attacks. Fix: Verify that cargo_metadata operations enforce HTTPS connections. Monitor any external registry accesses.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.