How to Add Support for a New Remote Data Source in GeoLibre

Adding a new remote data source to GeoLibre requires implementing a TypeScript provider interface, registering it through the plugin manager, and optionally exposing UI controls so users can select the source.

GeoLibre is built around a plugin architecture that lets the core application discover and use remote data providers without modifying the main desktop codebase. You can add support for a new remote data source by implementing the TimelapseProvider or custom plugin API, registering the implementation with GeoLibre’s extension points, and adding the module to the desktop application’s plugin loader. This keeps your provider fully integrated with GeoLibre’s store-driven architecture, UI, and persistence mechanisms.

Define the Provider Contract for Your Remote Data Source

GeoLibre distinguishes between time-based raster sources and generic remote file loaders. The interface you choose determines how the application catalogs and renders the data.

Implement a TimelapseProvider for Time-Series Imagery

Time-based sources must satisfy the TimelapseProvider interface. The maplibre-timelapse.ts plugin consumes this contract to build the frame picker and render the layer list.

// packages/plugins/src/plugins/timelapse-providers.ts
export const myAwesomeProvider: TimelapseProvider = {
  id: "my-awesome-provider",
  name: "My Awesome Imagery",
  attribution: "Imagery © MyCompany (2024)",
  listFrames: async () => {
    const resp = await fetch("https://my.api/imagery/years.json");
    const years = await resp.json();
    return years.map((y) => ({
      id: `my-awesome-${y}`,
      label: String(y),
      year: y,
      tileUrlTemplate: `https://my.cdn/tiles/${y}/{z}/{x}/{y}.png`,
      attribution: `My Awesome Imagery ${y}`,
      maxzoom: 12,
      tileSize: 256,
    }));
  },
};

registerTimelapseProvider(myAwesomeProvider);

Once registerTimelapseProvider is called, the control shows a picker entry labeled “My Awesome Imagery” and lazily fetches the frame list via listFrames.

Build a Custom Plugin for Generic Remote Rasters

For sources that do not fit the timelapse model, expose a command through the plugin API that calls GeoLibre’s core layer helpers.

// packages/plugins/src/plugins/my-remote-raster.ts
import { registerExternalNativeLayer } from "@geolibre/plugins";

export function registerMyRemoteRaster() {
  const api = {
    addMyRaster: (name: string, url: string) => {
      return createAppAPI().addCogLayer(name, url, { opacity: 0.9 });
    },
  };

  registerExternalNativeLayer({
    id: "my-remote-raster",
    name: "My Remote Raster",
    register: (app) => {
      app.addButton?.({
        label: "Add My Raster",
        onClick: () => api.addMyRaster("My Raster", "https://my.cdn/raster.tif"),
      });
    },
  });
}

The registerExternalNativeLayer function places the raster loader into GeoLibre’s PluginManager. The call to addCogLayer uses the same rendering pipeline as built-in raster layers, guaranteeing consistent styling and export behavior.

Register the Provider with the PluginManager

All providers must be added to the registerAll array in apps/geolibre-desktop/src/hooks/usePlugins.ts so they load at application startup.

// apps/geolibre-desktop/src/hooks/usePlugins.ts
manager.registerAll([
  // ...other built-in plugins
  import("@geolibre/plugins/src/plugins/my-remote-raster").then(m => m.registerMyRemoteRaster()),
]);

GeoLibre’s PluginManager automatically persists registered providers across sessions, so you do not need to write custom state-handling code.

Integrate the Provider into the GeoLibre UI

For TimelapseProvider implementations, setting the name field is enough to appear in the Timelapse picker because packages/plugins/src/plugins/maplibre-timelapse.ts enumerates registered providers automatically.

For custom plugins, attach UI entries through the register callback used with registerExternalNativeLayer, or add a toolbar menu via registerToolbarMenu. The createAppAPI implementation in usePlugins.ts demonstrates how built-in plugins attach controls to the Add-Data dialog.

Handle Remote File Classification

If your source introduces a new format or protocol, extend packages/plugins/src/plugins/remote-file-formats.ts. This file centralizes classifyPath logic, size limits, and format-specific handling. Keeping your rules here ensures remote file dialogs and validators recognize the source consistently.

Consume Remote Data Through Core APIs

Plugins do not manipulate the map directly. Instead, they call stable core APIs exposed through createAppAPI in usePlugins.ts. Methods such as addCogLayer, addTileLayer, and addWmtsLayer guarantee that your remote data receives the same styling, caching, and export behavior as native layers.

Test and Validate the Provider

Run the frontend test suite to confirm discovery and UI stability:

npm run test:frontend

Add or extend tests in tests/timelapse-provider.test.ts to verify provider registration and frame listing. Covering these paths ensures that upstream changes in the PluginManager do not silently break your remote data source.

Summary

  • Implement the correct contract—TimelapseProvider for time-series rasters or a custom plugin API for generic sources.
  • Call registerTimelapseProvider or registerExternalNativeLayer to expose the provider to the application.
  • Import the module in apps/geolibre-desktop/src/hooks/usePlugins.ts so the PluginManager loads it at startup.
  • Use core APIs like addCogLayer, addTileLayer, and addWmtsLayer to keep rendering consistent with built-in layers.
  • Extend remote-file-formats.ts when you need new classifyPath or size-limit rules.
  • Run npm run test:frontend and update tests/timelapse-provider.test.ts to prevent regressions.

Frequently Asked Questions

What is the difference between TimelapseProvider and RemoteFileFormat?

TimelapseProvider is a specialized interface for time-based raster catalogs that feed the Timelapse picker in maplibre-timelapse.ts. RemoteFileFormat lives in remote-file-formats.ts and handles generic path classification and loading rules. Choose TimelapseProvider when users need to scrub through temporal frames, and RemoteFileFormat when adding a static file type or protocol.

Do I need to modify GeoLibre’s core desktop code to add a remote provider?

No. All provider logic belongs in the @geolibre/plugins package or your own plugin module. The only change in the desktop app is a single import line in apps/geolibre-desktop/src/hooks/usePlugins.ts that registers your plugin with the PluginManager.

How does GeoLibre persist my provider across sessions?

Registration functions store the provider in the PluginManager state. Because the manager is integrated with GeoLibre’s store-driven architecture, the registration is automatically persisted and restored without manual local-storage code.

Which core API should I use for non-COG raster sources?

GeoLibre exposes addCogLayer for Cloud-Optimized GeoTIFFs, addTileLayer for XYZ endpoints, and addWmtsLayer for WMTS services. Select the method from createAppAPI that matches your source type to ensure proper tiling and caching.

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 →