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 a GeoLibreAppAPI instance.
  • deactivate(app) – Cleanup hook invoked when the plugin is disabled or unloaded.
  • handleUrlParameters – Optional method for deep-linking support when urlParameterNames is 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 MapLibre IControl instance to the map. The position parameter accepts GeoLibreMapControlPosition values (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 for url, 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 a Promise<string> resolving to the layer ID.
  • addZarrLayer(name, url, options) – Registers a Zarr store (v2/v3) as a raster layer. Returns a Promise<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’s CustomLayerInterface into 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.

  • 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 a bind option 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 .geolibre project file during load.

Utility Methods

  • fetchArrayBuffer(url) – Low-level fetch helper returning an ArrayBuffer for binary assets like COG headers.
  • fitBounds(bounds) – Zooms and pans to a [west, south, east, north] extent.
  • getMap() – Returns the underlying MapLibre Map instance (or null if 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:

  1. Registration – Built-in plugins are loaded from packages/plugins/src/index.ts, while external plugins are discovered as zip archives or directory bundles containing a plugin.json manifest.
  2. Activation – The host calls plugin.activate(app), supplying a fully populated GeoLibreAppAPI instance. The plugin immediately gains access to all API methods.
  3. 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.
  4. 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 GeoLibrePlugin interface and the GeoLibreAppAPI object 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:

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 →