Getting Started
Galavi is a WebGPU visualization library for shared-state scientific viewers. This page walks you from npm install to a rendered scene in about 30 lines of code.
Requirements
- A browser with WebGPU enabled (Chrome 113+, Edge 113+, Safari 17.4+, or Firefox Nightly).
- Node.js 18+ if you build with bundlers.
- A bundler that understands ES modules (Vite, esbuild, Rollup, Webpack 5, etc.). Galavi ships ESM only.
Install
npm install galavi
# or
bun add galavi
# or
pnpm add galaviGalavi has one runtime dependency: wgpu-matrix.
Minimal example
import { createGalavi } from "galavi";
const canvas = document.querySelector("canvas")!;
const galavi = await createGalavi({
state: {
physical: {
spatial: { size: [1024, 1024, 512], unit: "µm" },
},
exploration: {
camera: {
position : [512, 512, 1536],
target : [512, 512, 256],
up : [0, 1, 0],
navMode : "orbit",
},
lod: { mode: "auto", level: 0 },
},
layers: [
{
id : "volume",
type : "volume",
data: {
url : "https://server/data.zarr",
urlTemplate : "{url}:img3d:{level}:{c}:{z},{y},{x}",
},
options: {
dataSize : [1024, 1024, 512],
levelRange : [0, 6],
tileSize : [64, 64, 64],
selection : { c: 0 },
},
render: {
contrastLimits : [0, 0.05],
colormap : "gray",
},
},
],
},
views: {
main: {
type : "volume",
canvas,
layers : ["volume"],
controls: {
orbit : {},
fly : {},
resolution : {},
},
overlays: {
scalebar : { visibleWhenActive: true },
marker : { visible: false, shape: "cross" },
},
},
},
});
galavi.setActiveView("main");createGalavi() initializes WebGPU, mounts every view that has a canvas in its config, and returns a fully wired Galavi instance.
For delayed mounting (e.g. when the canvas does not exist at startup), omit canvas from the view config and call galavi.mount(viewId, canvas) later.
What you just built
- A state — physical space (1024³ voxels of µm), one volume layer, an orbit camera at the front of the volume.
- A view named
mainof typevolume, bound to your<canvas>, with three controls (orbit,fly,resolution) and two overlays (scalebar,marker). - A running render loop that pulls tiles on demand from the configured pyramid.
You can drive the scene through the high-level API:
galavi.setNavMode("fly");
galavi.setTarget([300, 400, 120]);
galavi.setLodMode("manual");
galavi.stepLod(1);
galavi.layer("volume")?.setRender({ opacity: 0.6 });
galavi.layer("volume")?.setOptions({ selection: { c: 2 } });
galavi.view("main").setOverlayOptions("marker", { visible: true });
const unsubscribe = galavi.subscribe((state) => {
console.log(state.exploration.camera);
});Multi-view scenes
A single Galavi instance can drive any number of views over the same state. Adding a slice view alongside the volume view is just another entry in views:
views: {
main: {
type : "volume",
canvas : volumeCanvas,
layers : ["volume"],
controls: { orbit: {}, fly: {}, resolution: {} },
},
slice: {
type : "slice",
canvas : sliceCanvas,
layers : ["sliceXY"],
controls: { panzoom: {}, resolution: {} },
overlays: {
scalebar : { visibleWhenActive: true },
marker : { visible: true, shape: "dot" },
},
},
},Both views share the same camera target and LOD state — moving the camera in one updates the other.
Next steps
- Read Design Philosophy to understand the state model and the constraints behind it.
- Read Architecture Notes for the layer/view split, tile residency, and per-frame protocol.
- Read Plugin Development to add your own layer, control, overlay, or view types.
- Browse the API Reference for the full public surface.
- Try the live examples.