How Turf.js Enables Client-Side Vector Processing in GeoLibre
GeoLibre performs spatial operations entirely in the browser using Turf.js algorithms that process GeoJSON FeatureCollections on the main thread, eliminating server dependencies for vector analysis.
GeoLibre (opengeos/GeoLibre) is an open-source geospatial framework designed for offline-first vector processing. By integrating Turf.js—a modular geospatial engine—at the core of its processing pipeline, the toolkit enables complex geometry operations to execute client-side across web, desktop, and Jupyter environments.
Architecture of the Processing Pipeline
The vector processing system is built on a plugin-style architecture where each operation is encapsulated as a ProcessingAlgorithm. These algorithms reside in the @geolibre/processing workspace and are registered in [registry.ts](https://github.com/opengeos/GeoLibre/blob/main/packages/processing/src/registry.ts) before being exposed to the UI.
The ProcessingAlgorithm Interface
Each algorithm exports a configuration object implementing the ProcessingAlgorithm interface. The [vector-tools.ts](https://github.com/opengeos/GeoLibre/blob/main/packages/processing/src/vector-tools.ts) module demonstrates this pattern, exporting tools like bufferTool and centroidTool that wrap Turf.js functions. Key properties include:
id– Unique identifier used by the registrysupportsSidecar– Boolean flag indicating whether the operation can run client-side (true) or requires the Python sidecar (false)run– Method receiving aProcessingContextand executing the Turf transformation
Client-Side Execution Context
When a user selects an algorithm from the Processing Menu in [ProcessingMenu.tsx](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/components/layout/toolbar/ProcessingMenu.tsx), the application constructs a ProcessingContext containing the active layer’s GeoJSON and parameter values. The algorithm’s run method then calls requireFeatures(ctx) to extract the FeatureCollection, ensuring all data remains in the browser’s memory space.
Built-In Vector Operations Using Turf.js
GeoLibre ships with pre-configured algorithms covering common GIS workflows. These implementations import Turf functions directly and handle GeoJSON validation automatically.
Buffer and Centroid Calculations
The bufferTool in [vector-tools.ts](https://github.com/opengeos/GeoLibre/blob/main/packages/processing/src/vector-tools.ts) demonstrates the standard pattern. It reads numeric parameters using numberParam(ctx, 'distance'), invokes buffer(fc, distance, {units}) from Turf.js (lines 185–192), and adds the result via ctx.addResultLayer (lines 94–95). The implementation handles both single features and collections, wrapping outputs in featureCollection to maintain consistent schema.
import { bufferTool } from '@geolibre/processing/src/vector-tools';
// ProcessingContext automatically populated by the UI
bufferTool.run(ctx);
Spatial Statistics
For analytical operations, [statistics-tools.ts](https://github.com/opengeos/GeoLibre/blob/main/packages/processing/src/statistics-tools.ts) provides Turf-based measurements including area, bounding box (bbox), and centroids. These functions operate identically to the geometry tools but return scalar values or summary statistics rather than new geometries, enabling attribute table calculations without leaving the client.
Creating Custom Turf.js Algorithms
Developers can extend the processing menu by authoring new ProcessingAlgorithm objects that invoke any Turf.js function. The following example implements a convex hull operation:
import convex from '@turf/convex';
import { featureCollection } from '@turf/helpers';
import type { ProcessingAlgorithm, ProcessingContext } from '@geolibre/processing/src/types';
export const convexHullTool: ProcessingAlgorithm = {
id: 'convexHull',
name: 'Convex Hull',
description: 'Create a convex hull polygon around all points',
group: 'Geometry',
supportsSidecar: true,
parameters: [{ id: 'layer', label: 'Input layer', type: 'layer', required: true }],
run: (ctx: ProcessingContext) => {
const fc = requireFeatures(ctx);
if (!fc) return;
const hull = convex(fc);
if (hull) ctx.addResultLayer?.('Convex Hull', hull);
},
};
After creating the file, register the export in registry.ts to surface the tool in the Processing Menu. Because supportsSidecar is set to true, this operation executes entirely in the browser using Turf’s JavaScript implementation, even in the Tauri desktop build.
Advanced Direct Turf.js Integration
For workflows requiring custom logic beyond the standard algorithm wrapper, you can import Turf functions directly and manipulate GeoJSON collections. This pattern mirrors the pairwise processing used internally in vector-tools.ts, which caps iterations at MAX_CLIENT_PAIRS to prevent blocking the main thread:
import { featureCollection } from '@turf/helpers';
import intersect from '@turf/intersect';
import type { FeatureCollection, Feature } from 'geojson';
function intersectLayers(
fcA: FeatureCollection,
fcB: FeatureCollection
): FeatureCollection {
const results: Feature[] = [];
for (const fA of fcA.features) {
for (const fB of fcB.features) {
const inter = intersect(fA as any, fB as any);
if (inter) results.push(inter as Feature);
}
}
return featureCollection(results);
}
This approach is useful for plugins or Jupyter notebook cells where you need to chain multiple Turf operations before adding the final result to the map via the store’s addResultLayer method.
Key Implementation Files
-
vector-tools.ts – Implements geometry-heavy algorithms (buffer, union, dissolve) using Turf.js functions. Lines 185–192 contain the buffer implementation; lines 41–59 handle parameter extraction.
-
statistics-tools.ts – Provides spatial statistics (area, bbox, centroid) leveraging Turf’s measurement modules.
-
registry.ts – Centralized collection point that imports all
ProcessingAlgorithmexports and exposes them to the UI layer. -
ProcessingMenu.tsx – React component that instantiates
ProcessingContextand dispatches algorithm execution based on user selection. -
derived-geometry.ts – Auxiliary helpers using Turf for map-side operations like bbox calculation and mask generation.
Summary
- GeoLibre executes vector processing client-side using Turf.js algorithms wrapped in
ProcessingAlgorithmobjects. - The vector-tools.ts module provides reference implementations for buffering, union, and centroid calculations.
- Algorithms operate on standard GeoJSON FeatureCollections, ensuring compatibility with Turf.js and avoiding data serialization to servers when
supportsSidecaris enabled. - Custom tools follow the same interface: import a Turf function, extract features via
requireFeatures, and return results throughctx.addResultLayer. - The architecture runs identically in web browsers, Tauri desktop applications, and Jupyter notebooks due to Turf’s pure JavaScript implementation.
Frequently Asked Questions
What is client-side vector processing in GeoLibre?
Client-side vector processing refers to the execution of spatial analysis algorithms—such as buffering, intersection, or centroid calculation—directly within the browser’s JavaScript runtime using Turf.js. As implemented in the @geolibre/processing workspace, these operations transform GeoJSON data on the main thread without transmitting information to a remote server or Python sidecar, enabling offline functionality and instantaneous feedback for interactive mapping workflows.
How does GeoLibre decide between client-side and server-side processing?
Each ProcessingAlgorithm declared in the registry includes a supportsSidecar boolean flag. When this flag is set to true, the system assumes the algorithm can execute using only Turf.js and JavaScript resources, keeping computation on the client. If an algorithm requires Python geospatial libraries (e.g., PySAL or rasterio), supportsSidecar is set to false, and the ProcessingContext routes the request to the Python sidecar instead.
Can I use Turf.js functions not included in the default processing menu?
Yes. You can import any Turf.js module into a custom algorithm file following the ProcessingAlgorithm interface pattern demonstrated in vector-tools.ts. After implementing the run method to call your desired Turf function—such as turf.clustersDbscan or turf.shortestPath—export the object and register it in registry.ts. The Processing Menu will automatically detect and display the new tool.
Does GeoLibre's client-side processing work offline?
Yes. Because Turf.js is a pure JavaScript library with no external dependencies, algorithms marked with supportsSidecar: true function completely offline once the application is loaded. This design applies to the web build (cached via service workers), the Tauri desktop build (local assets), and the Jupyter extension (local kernel), ensuring vector processing capabilities remain available without network connectivity.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →