OGJS

Decorative live WebGL2 render of a 40,000 node graph drawn as an elliptical disc, turning slowly on its axis. It demonstrates the renderer, not the force solver.

Keep the graph on the GPU.

Render, lay out, edit, and analyze large networks in the browser without blocking the interface.

40,000nodes in view
WebGL2instanced render
0position copies / tick
INITIALIZING

Numbers with a test attached.

Every report records the workload, seed, browser, GPU, viewport, and timing method. Runs compare only against compatible profiles, and the gate rejects regressions.

MEASUREMENT PROFILE / CLUSTERED-V2 seed 1831565813 · 1,000 nodes · 2,000 edges · Chrome 151 headless · SwiftShader software GPU · 1280×668 · v0.3.0-rc.2 · 2026-08-15
39.9 ms
median frame
40.5 ms
p95 frame
82.5 ms
build to first frame
4.17M q/s
picking throughput
57.2 ms
worker force · 10 iter
334.1 ms
GPU force · 10 iter, software-rendered
FRAME TIME, 15 HARD-SYNCED SAMPLES (ms) · warmup 5 · ogjs-benchmark/v1
38 40 42
Run on this device Download this report (JSON, v0.3.0-rc.2)

SwiftShader implements the GPU on the CPU. This profile is a regression gate, not a hardware speed claim. Your device will differ; measure it.

One position texture. Two readers.

Every node and edge attribute lives in a flat typed array. No per-element objects, no GC pressure, one contiguous upload path.

Node positions live in a single RGBA32F texture. It is the one place layout and rendering agree on.

Two writers. The GPU force pass writes positions inside a fragment shader. The worker force streams transferable frames, uploaded with one texSubImage2D per frame regardless of edge count.

Two readers. The node and edge shaders sample the same texture with texelFetch, so the simulation writes positions where the renderer already reads them.

A Canvas2D overlay composites labels with zoom level-of-detail over the WebGL2 output. Overlays stay crisp; the graph body stays instanced.

GPU forcewrites in a fragment pass
Graph dataSoA typed arrays
id → index map
Worker forcetransferable frames · one texSubImage2D
Position textureRGBA32F · written by the force pass, sampled by every draw
Node passSDF circles · texelFetch
Edge passscreen-space quads · texelFetch
Labels & overlaysCanvas2D · zoom LOD · composited last

Scroll to step through the pipeline · terminology from src/render and src/layout

Edit the graph without losing state.

Try it here: lasso a cluster, group it, slide the time window, then undo the whole edit. Every action below runs live in this page.

04:00 to 12:00

The shipped API behind each action: lasso.select() · og.groupVisually() / ungroup · timeline.setWindow() · history.undo() / redo()

Eight subsystems, one typed-array core.

Rendering and styling

Rule-based styles are evaluated once and compiled into typed-array writes.

styles.addNodeRule(fn)

A small surface for a large graph.

import { Ogjs } from '@mizansec/ogjs';

const og = new Ogjs({ container: '#viz' });
og.addNodes([{ id: 'a', label: 'Alice', size: 8 }, { id: 'b', label: 'Bob' }]);
og.addEdges([{ source: 'a', target: 'b' }]);

// worker-based force layout: streams frames, never blocks the UI
await og.layouts.force({ iterations: 300 });
og.camera.fit();
RUNTIME DEPENDENCIES
0
MODULE FORMAT
ES module with TypeScript declarations
WORKER ASSETS
Ship inside the package. Every release is verified by installing the packed tarball into an isolated consumer app.
ENTRYPOINTS
@mizansec/ogjs
@mizansec/ogjs/react
@mizansec/ogjs/vue
@mizansec/ogjs/svelte
REQUIREMENT
WebGL2. Ogjs fails fast with a clear error instead of a slow canvas path.

EVALUATION / COMMERCIAL LICENSE

Put your own data on the canvas.

Ogjs is commercial software. Evaluation use is permitted, with your own graph data. Production use requires a commercial license.

info@mizansec.com