hephaestus
A backend-agnostic 2D scene renderer for data visualization, written in Rust.
hephaestus ships two API levels in one crate. The scene API (SceneBuilder + primitives + layout) is a backend-neutral drawing surface. The plot API (plot::* — geoms, scales, themes, and the PlotComposition orchestrator) is a grammar-of-graphics layer built on top of it. Use whichever level fits; they are layered, not alternatives.
The public surface is deliberately the intersection of what Vello and Blend2D natively support, so drawing code runs unchanged as backends are added. The initial backend is Vello (GPU compute via wgpu); Blend2D (CPU raster), SVG, and PDF are planned.
Performance on dense, interactively-updated plots is the design driver. WASM is supported but is not the primary target.
Install
Quick start — the plot API
use VelloRenderer;
use ;
use ;
use Size;
use ;
use ;
use AxisSide;
use SceneBuilder;
use Renderer;
let comp = ;
let xs: = .map.collect;
let ys: = xs.iter.map.collect;
let mut plot = new.bind.bind;
plot.add_geom;
plot.set_title;
plot.add_axis;
plot.add_axis;
let mut view = new
.add_scale
.add_scale
.with_plot;
let = ;
let mut renderer = new.expect;
let mut pixels = vec!;
let bg: Color = rgb8;
renderer.render_to_buffer.expect;
Scales are shared by name: two plots that both bind("x", "t") resolve to the same Scale, so view.update_scale("t", ...) moves both panels from one call. Compositions nest — beside, stack, and friends build patchwork layouts whose axes and titles align across panels.
Quick start — the scene API
use VelloRenderer;
use rgb8;
use ;
use Shape;
let mut renderer = new.expect;
The renderer produces RGBA8 buffers. Surface presentation, event loops, and animation scheduling are the host's problem by design.
What's in the box
- Geoms — point, line, segment, rect, ellipse, polygon, wedge, ribbon, B-spline, ribbon-B-spline, geometry (WKT / WKB / GeoJSON), and three text geoms (mark, fit-to-box, along-path).
- Scales — continuous, discrete, binned, temporal, identity; log / sqrt / custom transforms; automatic and pinned breaks for both majors and minors; locale-aware label formatting.
- Projections — cartesian and polar, plus a
CustomProjectionhook. Non-linear projections densify edges so straight lines in data space curve correctly. - Chrome — axes, legends, colorbars, facet strips, titles, captions, all theme-driven.
- Themes — every chrome element is a themed element; no hardcoded constants in the render path.
- Rich text — a marquee-flavoured markdown subset with inline styling, block borders, and backgrounds.
- Picking — opt-in per renderer; emits pixel ids for hit-testing without a CPU post-pass.
Features
| Feature | Default | What it does |
|---|---|---|
vello |
✅ | GPU rasterizer via wgpu. |
png |
✅ | PNG writer, used by examples and tests. |
google-fonts |
Fetch named Google Fonts families on demand. Network call on cache miss; cache hits are offline. | |
chrono / time / jiff |
From impls between the temporal newtypes and the matching datetime library. Pick whichever your code already uses. |
|
geom-wkt / geom-wkb / geom-geojson |
Parsers for scales::Geometry. Hand-rolled and dependency-free, so toggling them only changes what constructors compile. |
|
blend2d / svg / pdf |
Placeholders. Wired through cargo so dependent crates can name them; no backend code behind them yet. |
The core types and traits build with --no-default-features, pulling in no wgpu, so downstream crates can target SceneBuilder without GPU dependencies.
Examples
Around 60 runnable examples live in examples/, each writing a PNG next to itself:
Status
Pre-1.0 and pre-stability: the API is expected to change as the remaining backends land. kurbo, peniko, and wgpu types appear in the public surface, so their major versions are part of this crate's semver contract.
License
MIT — see LICENSE.md.