vellumverse installs and loads the vellum graphics ecosystem in one step, the way tidyverse does for data science. Its packages carry a shared metaphor:
| package | role | analogy |
|---|---|---|
| vellum | low-level graphics backend, a Rust scene graph, unit/layout engine, and PNG/SVG/PDF renderer | grid |
| vellumplot | pipe-first grammar of graphics that compiles a plot spec into a vellum scene | ggplot2 |
| vellumwidget | client-side interactive HTML widgets for the scenes they produce |
plotly/htmlwidgets
|
vellum is the parchment, vellumplot is the pen, and vellumwidget is the annotation revealed on the page.
The three share one seam, and it is what makes them worth using together. vellum measures text and solves layout without a device, so a compiled scene can report where every element landed: scene_model() gives one row per drawn element with its data key and resolved device-pixel box. vellumplot compiles a plot spec into such a scene, and vellumwidget hosts that same scene in a browser, reading the table instead of re-drawing anything. So one specification yields a static figure, a vector file, and an interactive widget that cannot disagree about geometry, because there is a single solved layout behind all three.
For the longer argument, see a critical appraisal of grid and vellum’s design principles.
Installation
The ecosystem compiles a Rust crate (in vellum), so you need a Rust toolchain (cargo/rustc) alongside R. Then:
# install.packages("pak")
pak::pak("r-vellum/vellumverse")Usage
library(vellumverse)
#> ── Attaching packages ──────────────────────────────────── vellumverse 0.1.0 ──
#> ✔ vellum 0.1.0 ✔ vellumplot 0.1.0 ✔ vellumwidget 0.1.0That single call attaches all three core packages, so you can go from a data frame to an interactive plot in one pipeline:
library(vellumverse)
df <- data.frame(wt = mtcars$wt, mpg = mtcars$mpg, model = rownames(mtcars))
vplot(df) |> # vellumplot: grammar of graphics
mark_point(x = wt, y = mpg, color = mpg,
tooltip = model, data_id = model) |>
scale_color_continuous() |>
as_widget() # vellumwidget: interactive widgetvplot(), mark_point(), and the scales come from vellumplot; as_widget() comes from vellumwidget; both compile down to a vellum scene.
Helpers
vellumverse_packages() # the packages vellumverse bundles
vellumverse_conflicts() # functions masked across the ecosystemTo load the packages without the startup banner, set options(vellumverse.quiet = TRUE) before attaching.
