Bundler Integration
Modern web development rely on package manager to bring project dependencies. This section covers how published releases can be used within a JavaScript project.
Project setup
In the simple example we are going to use Vite with Vanilla JavaScript. The full code is available for reference here. Please note that you should use a concrete version, or "latest" for the @kitware/vtk-wasm package. Here, the example uses a relative path to the vtk-wasm project root, so the in-repo documentation stays relevant.
json
{
"name": "modern-app",
"private": true,
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"vite": "^6.3.5"
},
"dependencies": {
"@kitware/vtk-wasm": "file:../../.."
}
}html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Standalone VTK.wasm example</title>
</head>
<body>
<div id="app">
<canvas tabindex="-1" onclick="focus()"></canvas>
</div>
<script type="module" src="/src/main.js"></script>
</body>
</html>js
import "./style.css";
import { VtkWASMLoader } from "@kitware/vtk-wasm/vtk";
import { buildWASMScene } from "./example";
const loader = new VtkWASMLoader();
await loader.load("https://gitlab.kitware.com/api/v4/projects/13/packages/generic/vtk-wasm32-emscripten/9.5.20251215/vtk-9.5.20251215-wasm32-emscripten.tar.gz");
const vtk = loader.createNamespace();
buildWASMScene(vtk, "#app > canvas", "This scene passes the VTK.wasm bundle from GitLab registry to createNamespace()");js
export async function buildWASMScene(vtk, canvasSelector = "#vtk-wasm-window", titleText = "Sample VTK.wasm scene") {
function createSharedTextProperty() {
const textProperty = vtk.vtkTextProperty({ fontSize: 22 });
return textProperty;
}
async function createLookupTable(scalarRange) {
const lut = vtk.vtkColorTransferFunction();
await lut.setColorSpaceToHSV();
const colorSeries = vtk.vtkColorSeries({ colorScheme: 16 });
const numColors = await colorSeries.getNumberOfColors();
const scalarDiff = (scalarRange[1] - scalarRange[0]) / numColors;
for (let i = 0; i < numColors; i++) {
const color = await colorSeries.getColor(i);
const t = scalarRange[0] + i * scalarDiff;
lut.addRGBPoint(
t,
color[0] / 255,
color[1] / 255,
color[2] / 255,
);
}
await lut.build();
return lut;
}
async function createTitleTextActor(titleText, textProperty) {
const textActor = vtk.vtkTextActor({ input: titleText, textProperty });
const position = await textActor.getPositionCoordinate();
await position.setCoordinateSystemToNormalizedViewport();
return textActor;
}
// Create a VTK source. Output has a point data array named "Scalars" whose range is [0, PI].
const shapes = vtk.vtkPartitionedDataSetCollectionSource({ numberOfShapes: 2 });
const lut = await createLookupTable([0.0, Math.PI]);
const mapper = vtk.vtkCompositePolyDataMapper({ lookupTable: lut });
await mapper.setInputConnection(await shapes.getOutputPort());
const actor = vtk.vtkActor({ mapper, scale: [0.1, 0.1, 0.1] });
actor.property.edgeVisibility = true;
actor.property.edgeColor = [0.2, 0.2, 0.2];
const textProperty = createSharedTextProperty();
// Create an actor that displays the title.
const titleTextActor = await createTitleTextActor(titleText, textProperty);
// Setup rendering part
const renderer = vtk.vtkRenderer({ background: [0.384314, 0.364706, 0.352941] });
await renderer.addActor(actor);
await renderer.addActor(titleTextActor);
await renderer.resetCamera();
// Create a RenderWindow and bind it to a canvas in the DOM
const renderWindow = vtk.vtkRenderWindow({ canvasSelector });
await renderWindow.addRenderer(renderer);
const interactor = vtk.vtkRenderWindowInteractor({
canvasSelector,
renderWindow,
});
await interactor.interactorStyle.setCurrentStyleToTrackballCamera();
// Create camera widget
const cameraOrientation = vtk.vtkCameraOrientationWidget({ interactor, parentRenderer: renderer });
cameraOrientation.enabled = true;
// Display the scalar bar at the bottom with a horizontal orientation
const scalarBarActor = vtk.vtkScalarBarActor({
lookupTable: lut,
title: "Scalars",
titleTextProperty: textProperty,
labelTextProperty: textProperty,
annotationTextProperty: textProperty,
unconstrainedFontSize: true,
});
const scalarBar = vtk.vtkScalarBarWidget({ scalarBarActor, interactor, defaultRenderer: renderer });
const scalarBarRepresentation = await scalarBar.getRepresentation();
await scalarBarRepresentation.setOrientation(0); // 1: vertical, 0: horizontal
const lowerLeftPosition = await scalarBarRepresentation.getPositionCoordinate();
await lowerLeftPosition.setValue([0.1, 0.05]);
scalarBar.enabled = true;
// Trigger render and start interactor
await interactor.start();
}css
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
body {
margin: 0;
height: 100vh;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
}bash
npm install
npm run buildHere, the VTK.wasm bundle is downloaded in the browser directly from the Gitlab package registry. See the src/main.js file for the relevant code.