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

> Learn how to add a new remote data source to GeoLibre by implementing the TypeScript provider interface and registering it via the plugin manager. Enhance your geospatial data integration.

- Repository: [Open Geospatial Solutions/GeoLibre](https://github.com/opengeos/GeoLibre)
- Tags: how-to-guide
- Published: 2026-07-29

---

**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.

- **`TimelapseProvider`** – for time-series imagery that populates the Timelapse picker, defined in [`packages/plugins/src/plugins/timelapse-providers.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/plugins/src/plugins/timelapse-providers.ts).
- **`RemoteFileFormat`** – for classifying and handling generic remote files, defined in [`packages/plugins/src/plugins/remote-file-formats.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/plugins/src/plugins/remote-file-formats.ts).
- **Custom plugin API** – for sources that need bespoke ingestion or non-standard UI behavior.

### Implement a TimelapseProvider for Time-Series Imagery

Time-based sources must satisfy the `TimelapseProvider` interface. The [`maplibre-timelapse.ts`](https://github.com/opengeos/GeoLibre/blob/main/maplibre-timelapse.ts) plugin consumes this contract to build the frame picker and render the layer list.

```typescript
// 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.

```typescript
// 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`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/hooks/usePlugins.ts) so they load at application startup.

```typescript
// 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`](https://github.com/opengeos/GeoLibre/blob/main/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`](https://github.com/opengeos/GeoLibre/blob/main/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`](https://github.com/opengeos/GeoLibre/blob/main/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`](https://github.com/opengeos/GeoLibre/blob/main/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:

```bash
npm run test:frontend

```

Add or extend tests in [`tests/timelapse-provider.test.ts`](https://github.com/opengeos/GeoLibre/blob/main/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`](https://github.com/opengeos/GeoLibre/blob/main/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`](https://github.com/opengeos/GeoLibre/blob/main/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`](https://github.com/opengeos/GeoLibre/blob/main/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`](https://github.com/opengeos/GeoLibre/blob/main/maplibre-timelapse.ts). `RemoteFileFormat` lives in [`remote-file-formats.ts`](https://github.com/opengeos/GeoLibre/blob/main/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`](https://github.com/opengeos/GeoLibre/blob/main/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.