CLI tool
rustviz/rustviz avatar
rustviz/rustviz

RustViz: visualizing ownership and borrowing by walking rustc's HIR and MIR

Interactively Visualizing Ownership and Borrowing for Rust

2,851 stars75 forksRustMIT

At a glance

What is it?
RustViz turns short Rust snippets into interactive timeline SVGs that show when a binding becomes the owner and when references enter and leave scope. It is a teaching aid built as a rustc plugin, not a general static analyzer.
Who is it for?
RustViz fits instructors, tutorial authors and learners who want a diagram of ownership events next to the lines that cause them, and it fits mdBook authors who can tag blocks with ```rv. It is not the tool for auditing a large crate: the plugin walks a single-file crate, and it pins nightly-2025-08-20 through rust-toolchain.toml, so any CI that builds it has to accept that toolchain.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 144 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What RustViz actually solves for people learning ownership

Borrow checker errors describe a program in terms of lifetimes and moves, but the compiler output is text attached to spans. A learner reading `cannot move out of borrowed content` has to reconstruct, in their head, a timeline of which binding owned the value at each line. RustViz exists to draw that timeline instead. The README describes it as a teaching aid: paste a snippet and see when each binding becomes the resource owner, when references go in and out of scope, and which lines those events correspond to.

The audience is narrow on purpose. It is for instructors preparing lectures, for authors writing Rust tutorials, and for learners who want to see a specific confusing snippet rather than read another prose explanation of the three ownership rules. It is not a linter, it does not suggest fixes, and it does not claim to analyze whole crates. The README frames the plugin as walking HIR/MIR for a single-file crate, which is the scope you should assume.

How the rustc plugin turns a snippet into two SVG panels

The architecture has four entry points over one core. `rustviz-plugin/` is described in the README as the heart of the project: it walks HIR/MIR for a single-file crate and emits a code-panel SVG plus a timeline-panel SVG on stdout. It is built on Will Crichton's `rustc_plugin` / `rustc_utils` crates, the same family used by Flowistry and Aquascope, and it produces the `cargo-rv-plugin` and `rv-plugin-driver` binaries. Because it links against `rustc_private`, it is pinned to nightly-2025-08-20 via `rust-toolchain.toml`.

Above that plugin sit three consumers. `rustviz-lib` exposes `Rustviz::new(code)`, which shells out to the plugin and returns the two SVGs; the shared tooltip JavaScript for hover behavior also lives there. `rustviz-cli` wraps the library for one-shot rendering. `mdbook-rustviz` is a preprocessor that compiles each tagged snippet at build time and inlines the resulting SVGs into the rendered HTML. The playground is the fourth: a CodeMirror editor that posts snippets to a compile API. The README notes that the library's backend can be a local subprocess or sandboxed Docker, with `local` as the default for library use and the playground binary opting into `docker` for untrusted input. That split is the interesting design decision here: the same rendering path serves a trusted laptop and a public web endpoint, and the isolation boundary is a backend choice rather than a separate codebase.

Installing the rustviz CLI and rendering your first file

The README gives two install paths. The fastest is the published CLI plus an init step that installs the pinned nightly toolchain and the plugin. Run the first command, then the second; `rustviz init` runs `rustup toolchain install` and `cargo install` against the canonical RustViz repo, and it accepts `--dry-run` if you want to see the commands before they run.

bash
cargo install rustviz-cli   # the `rustviz` CLI binary
rustviz init                # installs nightly-2025-08-20 + the plugin

If you are contributing rather than consuming, the README points at the checkout path instead. `cargo xtask setup` is described as the canonical bootstrap for working on RustViz: it performs the toolchain and plugin install, the frontend build and the runner image build. `cargo xtask uninstall` reverses it, and by default it spares the rustup toolchain and the cargo `target/` tree.

bash
git clone https://github.com/rustviz/rustviz
cd rustviz
cargo xtask setup          # toolchain + plugin install + frontend build + runner image

With the plugin in place, rendering is one command per output format. The README's example writes two SVGs next to the input, `foo.code.svg` and `foo.timeline.svg`; the `html` variant writes a single self-contained page with both SVGs inlined and the tooltip JavaScript embedded, so it opens in a browser with no server and no external assets.

bash
rustviz svg foo.rs              # writes foo.code.svg + foo.timeline.svg
rustviz html foo.rs             # writes one self-contained HTML page

For programmatic use, the library API is short. `Rustviz::new(code)` calls the plugin under the hood and returns the two panels as strings, which you write out yourself. A runnable example is referenced at `rustviz-lib/examples/render_to_files.rs`.

rust
use rustviz_lib::Rustviz;

let rv = Rustviz::new(code)?;     // calls the plugin under the hood
fs::write("code.svg", rv.code_panel_string())?;
fs::write("timeline.svg", rv.timeline_panel_string())?;

The nightly pin and the single-file scope are real constraints

Two limitations follow directly from the design. The first is the toolchain. The plugin links against `rustc_private`, so it requires a specific nightly, pinned in `rust-toolchain.toml` to nightly-2025-08-20. That pin is not incidental: `rustc_private` APIs are unstable, which is why the project pins rather than tracks stable. The consequence for a team is that RustViz cannot simply ride whatever toolchain the rest of the repository uses; the README even notes that multiple checkouts share the rustup toolchain because they all pin the same nightly. If your build environment forbids nightly, or your organization treats nightly as unacceptable for build infrastructure, this project is the wrong tool regardless of how good the diagrams are.

The second is scope. The README says the plugin walks HIR/MIR for a single-file crate. That is a deliberate boundary around the teaching use case, but it means RustViz is not a way to understand ownership in a real multi-module codebase. A snippet that depends on types or functions defined elsewhere will not be the thing you feed it. The README also does not document rollback or a way to undo a partial `rustviz init`; `cargo xtask uninstall` exists for the checkout path and its `--help` describes what it touches, but for the CLI install path the documentation is silent on reversal. Treat the init step as something to run deliberately rather than casually.

RustViz compared with a general Rust visualization tool

The closest point of comparison named in the README is the family of tools the plugin is built on. RustViz uses the same `rustc_plugin` / `rustc_utils` crates as Flowistry and Aquascope, but the three answer different questions. Flowistry and Aquascope are general Rust visualization and analysis tools aimed at understanding real code; RustViz is deliberately scoped to short teaching snippets and to two specific panels: the code panel and the timeline panel. If you want to inspect data flow through a production crate, the general tools in that family are the right direction. If you want a diagram you can drop into a lecture slide showing the line where a reference goes out of scope, RustViz is built for exactly that, and it is not trying to be more.

The other comparison worth drawing is against the earlier annotation-based RustViz. The README states that earlier versions, deployed in the classroom and described in the VL/HCC 2022 paper, read hand-annotated source; the current repository is the compiler-integrated rewrite that plugs into `rustc` directly. The difference matters: the old approach showed a hand-curated approximation, while the current one reflects the real borrow checker's view. The original is still available on the `rv1-final` branch and tag, with a matching GitHub Release, so anyone with annotation-based course material can keep using it.

Embedding RustViz diagrams in an mdBook

For tutorial authors, the mdbook preprocessor is the most useful entry point. You declare the preprocessor in `book.toml`, then tag code blocks with `rv` instead of `rust`. The preprocessor compiles each snippet through the plugin at build time and inlines the resulting SVGs into the rendered HTML, with tooltip glue for hover-driven exploration.

toml
# book.toml
[preprocessor.rustviz]

The block syntax is the same fenced code you already write, with the language tag changed. Setup instructions live in `mdbook-rustviz/README.md`, and `mdbook-rustviz/test-book/` holds a small worked example.

`

markdown

rv fn main() { let s = String::from("hello"); println!("{}", s); }

code

`

The README points at a full-scale example: the hands-on Rust tutorial at `rustviz/tutorial`, deployed at `rustviz.github.io/tutorial/`, is built this way. The trade-off to weigh is build time. Because the preprocessor compiles each snippet through the plugin during the book build, every tagged block adds a compile step, and the whole thing depends on the pinned nightly being present on the machine doing the build. For a book with a handful of ownership examples that is a reasonable cost; for a book with hundreds of code blocks it is not.

Licence and the cost of keeping up with the pin

RustViz is MIT licensed, which is permissive and imposes few obligations beyond retaining the licence text; this is a description of the licence identifier, not legal advice, and anyone with specific questions should read the LICENSE file in the repository root. The practical upgrade cost is the toolchain pin. Because the plugin depends on `rustc_private` and is pinned to nightly-2025-08-20 in `rust-toolchain.toml`, moving to a newer nightly is not a routine dependency bump. It means updating the plugin against whatever internal APIs changed, which is the kind of work that only makes sense if someone is actively developing the plugin. The last push to the repository was on 2026-05-10, and the `rv1-final` release, described as the final annotation-based release, was tagged on 2026-05-05. The README does not describe a support policy for older nightlies, so if you depend on RustViz in a course that runs for several semesters, plan for the pin to become stale and decide in advance whether you will carry the update yourself.

Editorial conclusion

RustViz fits instructors, tutorial authors and learners who want a diagram of ownership events next to the lines that cause them, and it fits mdBook authors who can tag blocks with ```rv. It is not the tool for auditing a large crate: the plugin walks a single-file crate, and it pins nightly-2025-08-20 through rust-toolchain.toml, so any CI that builds it has to accept that toolchain. Before adopting it, run rustviz svg on one representative snippet and check that the two SVGs it writes, foo.code.svg and foo.timeline.svg, show the events you care about; then confirm whether your pipeline can live with the plugin's rustc_private dependency.

Frequently asked questions

Does RustViz need a nightly Rust toolchain?

Yes. The plugin links against `rustc_private`, so it requires a specific nightly, pinned to nightly-2025-08-20 via `rust-toolchain.toml`. Running `rustviz init` installs that toolchain along with the plugin.

What files does rustviz svg produce?

The README's example writes two files next to the input: `foo.code.svg` and `foo.timeline.svg`. The `rustviz html` command instead writes a single self-contained HTML page with both SVGs inlined and the tooltip JavaScript embedded.

Can RustViz analyze a whole crate?

No. The README describes the plugin as walking HIR/MIR for a single-file crate, which matches its use as a teaching aid for short snippets. Multi-module codebases are outside that scope.

How do I embed RustViz diagrams in an mdBook?

Add a `[preprocessor.rustviz]` section to `book.toml` and tag code blocks with `rv` instead of `rust`. The preprocessor compiles each snippet through the plugin at build time and inlines the resulting SVGs into the rendered HTML.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. rustviz/rustviz on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/rustviz-rustviz.svg)](https://hysenlabs.com/projects/rustviz-rustviz)