Skip to content

The WebAssembly Backend

Nodus’s compute core is written in Rust and compiled to WebAssembly. The WASM backend is the switch that routes heavy work — layouts, graph algorithms, geometry — through that compiled code instead of JavaScript. This page explains how to enable it and what it accelerates.

For the architecture behind it — the crates, the data split, why it’s built this way — see Architecture. This page is the practical, activation-focused companion.

Turn on the compiled compute backend with a single call:

import { Nodus, enableWasmBackend } from '@kortexya/nodus';
enableWasmBackend();
const nodus = new Nodus({ container: document.getElementById('graph') });

If you’d rather offload only part of the pipeline, target a specific subsystem with useWasm:

import { useWasm } from '@kortexya/nodus';
useWasm('layout'); // offload layout computation
useWasm('geometry'); // offload geometry kernels
useWasm('all'); // offload everything (equivalent to the full backend)

The Subsystem argument is 'layout' | 'geometry' | 'all'. This lets you, for example, run layouts in compiled code while keeping a particular path on the JS side, or roll the backend out subsystem by subsystem.

For more control over which backend serves which workload, use configureBackends:

import { configureBackends } from '@kortexya/nodus';
configureBackends({ /* backend configuration */ });

configureBackends is the low-level knob beneath enableWasmBackend / useWasm; most applications won’t need it. The related Backend and Subsystem types are exported for typed configuration.

When the backend is active, these workloads run in compiled Rust rather than JavaScript:

  • Force layout — the iterative physics simulation.
  • Shortest paths — Bellman-Ford, Johnson and Dijkstra.
  • Hierarchical layout — the Sugiyama layered algorithm.
  • Stress minimization — used in layout and hypergraph optimization.
  • Geometry kernels — distances, intersections, polygons, curves.
  • Spatial indexing — the structures that power hit-testing and neighbour queries.

These are exactly the arithmetic-heavy, branchy workloads that compile well to WASM and run poorly as idiomatic JavaScript — which is why offloading them is the performance win.

By default the backend runs its heavy operations in a Web Worker, with the WASM module instantiated inside the worker. The benefit: a large layout or a graph algorithm can churn without freezing the main thread, so panning, zooming and the rest of your UI stay responsive.

This is why layout and algorithm calls are asynchronous — you await them (see Layouts). The worker communicates over ordinary postMessage, which means:

import { Nodus, enableWasmBackend } from '@kortexya/nodus';
enableWasmBackend();
const nodus = new Nodus({ container: document.getElementById('graph') });
await nodus.setGraph({
nodes: [{ id: 'a' }, { id: 'b' }, { id: 'c' }],
edges: [
{ source: 'a', target: 'b' },
{ source: 'b', target: 'c' },
],
});
// Runs the force simulation in compiled Rust, off the main thread.
await nodus.layouts.force();
await nodus.view.locateGraph();
  • Architecture — the crates, the JS/WASM boundary, and how data is split between Rust memory and JavaScript.
  • Layouts — the async, cancellable layouts this backend accelerates.
  • Algorithms — the graph algorithms offloaded to compiled code.
  • The Rendering Pipeline — the rendering side of the WASM story.