How GeoLibre Executes Whitebox Tools Client-Side with WebAssembly

GeoLibre runs Whitebox GIS algorithms entirely in the browser by compiling the Whitebox-Next-Gen binary to WebAssembly (WASM) and exposing a thin JavaScript API that handles tool discovery, execution in a Web Worker, and raster post-processing without any server round-trip.

GeoLibre is an open-source geospatial processing environment maintained by opengeos/GeoLibre. Its WebAssembly-based geoprocessing toolbox enables complex spatial analysis using Whitebox tools directly in the browser, eliminating server-side processing delays and keeping sensitive data local to the client.

Tool Discovery and Catalog Management

The execution pipeline begins in packages/processing/src/wasm-client.ts. The listWhiteboxWasmTools() function reads the embedded WASM manifest and merges it with the Whitebox catalog snapshot retrieved from the sidecar via packages/processing/src/sidecar-client.ts. The catalog generation script at scripts/gen-whitebox-menu-catalog.mjs synchronizes Whitebox-only WASM tools to ensure the manifest remains current.

Each tool’s parameters are normalized by manifestToWhiteboxTool() and mergeToolParameters(). The UI components, specifically apps/geolibre-desktop/src/components/processing/ProcessingDialog.tsx, construct dynamic input forms from WhiteboxToolParameter objects, presenting users with the complete Whitebox tool catalog without requiring server queries.

Parameter Handling and Request Construction

When a user selects a tool, the frontend builds a RunWhiteboxToolRequest object. This interface defines the toolId, input layers (referencing the Z-state store by ID), and tool-specific parameters such as z_factor for slope calculations or tolerance values for vector operations.

The ProcessingDialog.tsx component manages form state and validation, ensuring that raster and vector inputs are correctly referenced before execution begins. Validated requests are then passed to the WASM execution layer.

WASM Execution in a Web Worker

To maintain UI responsiveness during heavy computation, GeoLibre spawns a dedicated Web Worker that instantiates the Whitebox WASM module.

Worker Initialization and Messaging

The runWhiteboxToolWasm() function in wasm-client.ts posts the RunWhiteboxToolRequest to packages/processing/src/wasm-convert.worker.ts via postMessage. Inside the worker, the WASM module (geolibre-wasm) is instantiated, the appropriate Whitebox binary is located, and the tool is executed with the supplied arguments.

Job Tracking and Output Retrieval

The worker returns a WhiteboxJob object containing execution status, stdout and stderr streams, and a Uint8Array of the raw output file. The main thread updates apps/geolibre-desktop/src/components/processing/ProcessingHistoryDialog.tsx to display real-time progress and results, allowing users to monitor long-running geoprocessing tasks without blocking the interface.

Raster Post-Processing and Layer Integration

Whitebox raster outputs often require format conversion before visualization. The ensureWhiteboxRasterCog() function in wasm-client.ts rewrites striped GeoTIFF outputs into Cloud-Optimized GeoTIFFs (COG) that MapLibre can stream efficiently using HTTP range requests.

After conversion, processed outputs integrate into the Z-state store (@geolibre/core). The MapController.syncLayers method in @geolibre/map then creates corresponding MapLibre sources and layers, making results appear instantly on the map canvas.

Implementation Example

The following example demonstrates listing available tools, constructing a slope analysis request, and executing it client-side:

// 1️⃣ List available WASM-based Whitebox tools
import { listWhiteboxWasmTools } from '@geolibre/processing';
const wasmTools = await listWhiteboxWasmTools(); // → ["reproject_vector", "slope", …]

// 2️⃣ Build a request for the "slope" tool
import type { RunWhiteboxToolRequest } from '@geolibre/processing';
const request: RunWhiteboxToolRequest = {
  toolId: 'slope',
  input: { raster: myRasterLayerId },   // raster layer already loaded in the store
  parameters: { z_factor: '2' },       // Whitebox-specific options
};

// 3️⃣ Execute it locally in the browser
import { runWhiteboxToolWasm } from '@geolibre/processing';
const job = await runWhiteboxToolWasm(request);

// 4️⃣ Convert to COG and add as a layer
import { ensureWhiteboxRasterCog } from '@geolibre/processing';
const cogBytes = await ensureWhiteboxRasterCog(job.output);
await addRasterLayer({ id: 'slope-output', bytes: cogBytes });

Summary

  • Tool discovery occurs via listWhiteboxWasmTools() in packages/processing/src/wasm-client.ts, merging embedded manifests with sidecar catalog data from packages/processing/src/sidecar-client.ts.
  • Execution happens inside packages/processing/src/wasm-convert.worker.ts, which instantiates the WASM module and runs Whitebox binaries in an isolated thread to prevent UI blocking.
  • Job tracking returns WhiteboxJob objects containing output bytes and logs, updating the Processing History UI in real-time via ProcessingHistoryDialog.tsx.
  • Raster post-processing uses ensureWhiteboxRasterCog() to convert outputs to MapLibre-compatible Cloud-Optimized GeoTIFFs before layer integration.
  • Zero server dependency: All processing occurs client-side, with network activity limited to optional catalog downloads and initial WASM asset fetching.

Frequently Asked Questions

How does GeoLibre handle large raster datasets in WebAssembly?

GeoLibre processes large rasters by executing Whitebox tools inside a Web Worker using wasm-convert.worker.ts, preventing UI blocking during computation. The ensureWhiteboxRasterCog() function in packages/processing/src/wasm-client.ts converts striped GeoTIFF outputs to Cloud-Optimized GeoTIFFs (COG), enabling efficient streaming and visualization without loading entire files into browser memory.

What is the role of the sidecar client in the WebAssembly pipeline?

The sidecar client (packages/processing/src/sidecar-client.ts) fetches the remote Whitebox catalog snapshot, which listWhiteboxWasmTools() merges with the embedded WASM manifest. This hybrid approach allows GeoLibre to display up-to-date tool definitions while maintaining offline capability through the embedded manifest stored in the browser.

Can I run Whitebox tools without an internet connection?

Yes. Once the WASM module and embedded manifest are loaded, GeoLibre executes Whitebox tools entirely within the browser using the compiled Whitebox-Next-Gen binaries. The only network requirements are the initial download of WASM assets and optional catalog updates; subsequent processing operates offline.

How are tool parameters validated before execution?

Parameters are normalized through manifestToWhiteboxTool() and mergeToolParameters() in wasm-client.ts. The ProcessingDialog.tsx UI component constructs forms from WhiteboxToolParameter objects, ensuring type safety and required field validation before constructing the RunWhiteboxToolRequest sent to the worker.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →