The Rendering Pipeline
Nodus can draw the same graph through several back-ends. Which one runs depends on what the browser supports and on what you ask for. This page explains the renderers, how one is selected, and what each is good for.
For how the renderer is implemented in Rust, see Architecture.
The renderers
| Renderer | Name | Backend | Role |
|---|---|---|---|
| GPU renderer | wasm | WebGPU (preferred), WebGL2 | High-performance interactive rendering |
| Canvas 2D | canvas | HTML Canvas 2D | High-quality CPU fallback; works everywhere |
| SVG | — | DOM/SVG | Vector output for export |
The GPU renderer (wasm)
The wasm renderer is the Rust wgpu renderer compiled to
WebAssembly. It prefers WebGPU (navigator.gpu) — modern, with compute
shaders — and is also built with a WebGL2 backend for browsers that don’t
expose WebGPU yet.
It uses instanced rendering and GPU-side attribute packing to draw very large graphs efficiently, with custom WGSL shaders for node shapes, edges (including curves, dashes, arrowheads and self-loops), labels and icons.
Try it live — 1,500 nodes rendered and pannable in the browser:
The Canvas 2D renderer (canvas)
A high-quality CPU rasterizer. It is the practical fallback for browsers without WebGPU, and it renders the full visual model — node shapes and pies, strokes, halos, icons, labels (including positioned label pills), edge shapes (curves, dashes, chevrons), and secondary text. It’s reliable everywhere and a good default when you don’t need GPU throughput.
SVG output
The SVG path produces vector output, which is what you want for export — print-quality images or handing a diagram to a vector editor. See Exporting.
How a renderer is selected
You can let Nodus choose, or request one explicitly.
Automatic
By default Nodus uses the GPU renderer when WebGPU is available and falls back to Canvas 2D when it isn’t. Either way you get a render — the fallback is automatic and silent.
Explicit
import { Nodus, isWebGpuSupported } from '@kortexya/nodus';
const nodus = new Nodus({ container: 'graph', renderer: isWebGpuSupported() ? 'wasm' : 'canvas',});isWebGpuSupported() is a synchronous capability check (navigator.gpu is
present). The available renderer names are 'wasm' and 'canvas'; requesting
an unknown name throws an error that lists the available renderers, so typos
fail loudly instead of silently substituting a different renderer.
The "webgl" renderer is not available. Available renderers: canvas, wasm.The decision in practice
┌─────────────────────────┐ │ renderer requested? │ └───────────┬─────────────┘ explicit │ not specified ┌────────────────┘ │ ▼ ▼ use it (or throw if ┌─────────────────┐ unknown) │ WebGPU present? │ └───────┬─────────┘ yes │ no ┌──────────┘ │ ▼ ▼ GPU renderer Canvas 2D (`wasm`, WebGPU) (`canvas`)Choosing for your app
- Large or highly interactive graphs — prefer the GPU renderer. On WebGPU you get the most headroom; on WebGL2 you still get GPU-accelerated drawing.
- Maximum compatibility — the Canvas 2D renderer runs anywhere and matches the visual model closely. It’s the automatic fallback, so you rarely need to select it by hand.
- Export — render to SVG (vector) or grab a raster snapshot with
nodus.view.getImageData(). See Exporting.
Sizing and sharpness
The renderer matches your container’s size and device pixel ratio, and re-syncs
when the container resizes — so the graph stays crisp on high-DPI displays and
after layout changes. You can force a re-measure with nodus.view.forceResize()
and read or set the drawing size with nodus.view.getSize() /
nodus.view.setSize({ width, height }).
Next
- Camera & Coordinates — zoom, pan, rotate, and converting between screen and graph space.
- Styling — the visual attributes every renderer draws.
- Exporting — raster and vector output.