GeoLibre Plugin APIs: The Complete Developer Guide to Custom Extensions
GeoLibre exposes a typed JavaScript API built around the GeoLibrePlugin interface and GeoLibreAppAPI object, enabling developers to control maps, manage layers, register UI components, and coordinate between plugins.
GeoLibre is an open-source geospatial platform designed for desktop, web, and Jupyter environments. The GeoLibre plugin APIs provide a comprehensive contract that allows third-party developers to extend functionality without modifying core source code. This guide documents the full API surface available in the opengeos/GeoLibre repository, from lifecycle management to cloud-native data integration.
Core Plugin Interface
Every plugin must implement the GeoLibrePlugin interface defined in docs/plugin-api.md. This contract declares the plugin’s identity and lifecycle hooks.
Key properties include:
id,name,version– Unique identifiers and versioning metadata.activeByDefault– Optional boolean to auto-activate on startup.activate(app)– Called by the host to initialize the plugin, receiving aGeoLibreAppAPIinstance.deactivate(app)– Cleanup hook invoked when the plugin is disabled or unloaded.handleUrlParameters– Optional method for deep-linking support whenurlParameterNamesis declared.
The GeoLibreAppAPI object passed to activate contains the full surface area of available methods, which are typed as potentially undefined to accommodate host variants that may not implement specific features. The recommended calling pattern uses optional chaining:
app.addTileLayer?.('My Tiles', 'https://my.tiles/{z}/{x}/{y}.png');
Map Control and Basemap APIs
Plugins have granular control over the map viewport and built-in controls through the following methods:
setBasemap(styleUrl)– Switches the base style using a MapLibre GL style URL.getActiveBasemap()– Returns the currently active base-style URL.addMapControl(control, position?)– Adds a custom MapLibreIControlinstance to the map. Thepositionparameter acceptsGeoLibreMapControlPositionvalues (top-left,top-right,bottom-left,bottom-right).removeMapControl(control)– Removes a previously added custom control.setBuiltInMapControlVisible(control, visible)– Toggles visibility of built-in controls (navigation, fullscreen, terrain).setBuiltInMapControlPosition(control, position)– Repositions built-in controls to a different corner.
These methods are implemented in the host application and documented in docs/plugin-api.md under the App API section.
Layer Management APIs
GeoLibre plugins can programmatically add and manage geospatial data layers, which automatically appear in the Layers panel and persist in project files.
Vector Data
addGeoJsonLayer(name, data, sourcePath?)– Registers a GeoJSON feature collection as a native layer. The layer appears in the UI and is stored in the global Zustand state store.
Raster and Tile Layers
addTileLayer(name, url, options?)– Adds an XYZ tile source (e.g., satellite imagery).addWmtsLayer(name, url, options?)– Adds a WMTS source.addWmsLayer(name, options)– Adds a WMS source with configuration forurl,layers,styles, and other parameters.
Cloud-Native Formats
addCogLayer(name, url, options?)– Loads a Cloud-Optimized GeoTIFF client-side. Supports band selection, colormaps, and nodata handling. Returns aPromise<string>resolving to the layer ID.addZarrLayer(name, url, options)– Registers a Zarr store (v2/v3) as a raster layer. Returns aPromise<string>.setZarrLayerSelector(layerId, selector)– Updates the non-spatial slice of a Zarr layer (e.g., time dimension).queryZarrLayer(layerId, geometry, selector?, options?)– Reads values under a point or polygon for identify operations or zonal statistics.
Custom WebGL Layers
registerExternalNativeLayer(registration)– Mirrors a layer added directly via MapLibre’sCustomLayerInterfaceinto GeoLibre’s layer store. This enables UI panel integration and project persistence for custom WebGL layers.unregisterExternalNativeLayer(id)– Removes the external layer registration.
UI Extension APIs
Plugins can extend the GeoLibre interface by registering panels and menus that render in isolated DOM containers.
Right-Sidebar Panels
registerRightPanel(panel)– Creates a dockable panel beside the built-in Style/Layers sidebars. Returns an unregister function.unregisterRightPanel(id)– Removes the panel registration.openRightPanel(id),closeRightPanel(id),collapseRightPanel(id)– Control panel visibility and docking state.
The panel object requires an id, title, defaultWidth, and a render(container: HTMLElement) function that returns a cleanup callback.
Floating Panels
registerFloatingPanel(panel)– Adds a draggable overlay card that does not resize the map canvas.unregisterFloatingPanel(id)– Removes the floating panel.openFloatingPanel(id),closeFloatingPanel(id),getOpenFloatingPanels()– Manage floating panels at runtime.
Toolbar Menus
registerToolbarMenu(menu)– Adds a top-level menu to the GeoLibre banner, supporting submenus, actions, and separators.unregisterToolbarMenu(id)– Removes the menu.
Map Controls
Custom MapLibre controls added via addMapControl integrate directly with the map canvas, while the built-in control methods manage the standard navigation widgets.
Advanced Integration Features
Temporal Data Support
registerTemporalLayer(layerId, adapter, options?)– Links a layer’s time dimension to the global Time Slider. Accepts abindoption for custom frame-based animations.unregisterTemporalLayer(layerId)– Disconnects the layer from temporal controls.
Plugin Coordination
activatePlugin(id, projectState?)– Programmatically enables another plugin, optionally supplying a state patch applied after activation.deactivatePlugin(id)– Disables a target plugin.
Deck.gl Integration
getDeckGL()– Returns a promise resolving to the host’s shared Deck.gl modules (core,layers,geoLayers,meshLayers,mapbox). Plugins must render on this single instance to avoid version conflicts.
Project State Persistence
getProjectState()– Serializes the current plugin-specific settings.applyProjectState(state)– Restores settings from a.geolibreproject file during load.
Utility Methods
fetchArrayBuffer(url)– Low-level fetch helper returning anArrayBufferfor binary assets like COG headers.fitBounds(bounds)– Zooms and pans to a[west, south, east, north]extent.getMap()– Returns the underlying MapLibreMapinstance (ornullif not ready).
Plugin Architecture and Lifecycle
The plugin system is orchestrated by the PluginManager class in packages/plugins/src/plugin-manager.ts. This manager maintains a map of PluginRegistryEntry objects defined in apps/geolibre-desktop/src/lib/plugin-registry.ts.
The lifecycle follows this sequence:
- Registration – Built-in plugins are loaded from
packages/plugins/src/index.ts, while external plugins are discovered as zip archives or directory bundles containing aplugin.jsonmanifest. - Activation – The host calls
plugin.activate(app), supplying a fully populatedGeoLibreAppAPIinstance. The plugin immediately gains access to all API methods. - State Synchronization – Layers added via
addGeoJsonLayer,addCogLayer, or similar methods are automatically recorded in the global store, enabling persistence and interaction with the style editor and time slider. - Cleanup – When disabled,
plugin.deactivate(app)is invoked, allowing removal of controls, panels, and event listeners.
Security and trust for external plugins are handled by apps/geolibre-desktop/src/lib/plugin-integrity.ts (hashing and manifest validation) and apps/geolibre-desktop/src/lib/plugin-trust.ts (sandboxing and permissions). The startup hook in apps/geolibre-desktop/src/hooks/usePlugins.ts coordinates loading of built-in and external bundles.
Summary
- The GeoLibre plugin APIs center on the
GeoLibrePlugininterface and theGeoLibreAppAPIobject provided during activation. - Plugins can add vector, raster, COG, and Zarr layers that automatically integrate with the Layers panel and project persistence.
- UI extensions include right-sidebar panels, floating panels, and toolbar menus that render in isolated DOM containers without sharing React context.
- Advanced features support temporal animations, Deck.gl visualization, cross-plugin activation, and URL parameter handling.
- All API methods are optional (
undefined-able) to support host variants; use optional chaining for defensive coding.
Frequently Asked Questions
What programming languages are supported for GeoLibre plugins?
GeoLibre plugins are written in TypeScript or JavaScript. The API is fully typed and distributed via the @geolibre/plugins package, providing IntelliSense for the GeoLibrePlugin interface and GeoLibreAppAPI methods.
How do I persist plugin settings across sessions?
Use the getProjectState and applyProjectState methods available on the GeoLibreAppAPI object. These allow you to serialize plugin-specific configuration into the .geolibre project file and restore it when the project is reopened or the plugin is reactivated.
Can plugins activate or communicate with each other?
Yes. Plugins can programmatically control each other using activatePlugin(id) and deactivatePlugin(id), optionally passing state patches during activation. They can also share data indirectly through the project state JSON or by registering layers that other plugins can query.
How do I add a custom UI panel to the GeoLibre interface?
Register a right-sidebar panel using registerRightPanel for dockable sidebars, or a floating panel using registerFloatingPanel for draggable overlays. Both methods accept a render function that receives an HTMLElement container where you can mount your UI, and return a cleanup function for resource management.
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 →