Skip to content

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

RendererNameBackendRole
GPU rendererwasmWebGPU (preferred), WebGL2High-performance interactive rendering
Canvas 2DcanvasHTML Canvas 2DHigh-quality CPU fallback; works everywhere
SVGDOM/SVGVector 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:

1,500 nodes, live Open in new tab ↗

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.