GeoLibre Repository File Management Tools: A Complete Technical Guide

GeoLibre manages geospatial files through a centralized Zustand store with a unified addGeoJsonLayer API that handles client-side ingestion, backend conversion, and plugin-driven data sources.

GeoLibre is a modern, store-driven web-desktop GIS application in the opengeos/GeoLibre repository. Every piece of geospatial data is treated as a "layer" stored in a central state container, with file operations funneled through a small, well-defined API exposed to plugins, the UI, and a Python side-car. Understanding these GeoLibre file management tools is essential for developers extending the platform or integrating custom data pipelines.

Core Store Architecture

The foundation of GeoLibre's file management is a single source of truth implemented in Zustand.

The Zustand Store

The store lives in packages/core/src/store.ts. It maintains a map of GeoLibreLayer records, each containing:

  • Unique layer ID
  • Human-readable name
  • Source type (geojson, vector, raster, etc.)
  • Reference to raw data
  • UI style defaults

When any file is imported—whether through drag-and-drop, file picker, or programmatic plugin—the UI calls addGeoJsonLayer (or raster/tile equivalents). This function performs three atomic operations:

  1. Generates a unique layer ID
  2. Inserts a new GeoLibreLayer entry into the store
  3. Seeds the layer with DEFAULT_LAYER_STYLE for immediate rendering

The public API signature is defined in packages/plugins/src/types.ts:

addGeoJsonLayer: (name: string, data: FeatureCollection, sourcePath?: string) => string;

Client-Side File Ingestion

GeoLibre handles most vector formats directly in the browser without server round-trips.

In-Browser Vector Processing

Vector files (Shapefile, GeoJSON, Parquet, FlatGeobuf) are read by DuckDB-WASM Spatial using its ST_Read function. The addGeoJsonLayer helper converts raw data to a standard GeoCollection and writes it to the store. The UI then triggers MapCanvas → MapController.syncLayers to materialize the layer in MapLibre GL.

Key implementation files:

Client-Side Example

// Add a local GeoJSON file (client-side)
import { useAppStore } from '@geolibre/core';
import myData from './my-data.geojson';

const layerId = useAppStore.getState().addGeoJsonLayer('My Layer', myData);
// The layer now appears on the map with default styling.

Backend Side-Car for Heavy-Weight Formats

For formats exceeding browser capabilities, GeoLibre runs a FastAPI side-car in backend/geolibre_server.

Server-Side Conversion Pipeline

The side-car exposes /vector and /raster endpoints accepting multipart/form-data uploads. The client uploads files via fetch or the built-in "Conversion" dialog; the server returns converted GeoJSON or MBTiles that addGeoJsonLayer or addRasterLayer consumes.

Key implementation: backend/geolibre_server/app/conversion.py

Backend Upload Example


# Upload a large raster to the side-car (backend)

import requests

files = {'file': open('large.tif', 'rb')}
resp = requests.post('http://127.0.0.1:8765/raster', files=files)
raster_id = resp.json()['layerId']

# After the server finishes conversion you can call:

useAppStore.getState().addRasterLayer('Large Raster', raster_id)

Plugin-Driven File Sources

Plugins extend GeoLibre's file management to external services without duplicating core logic.

Consistent Layer Model

Plugins for STAC, OGC services, and custom APIs all call the same core API, ensuring uniform behavior. The plugin interface in packages/plugins/src/types.ts guarantees this consistency.

// Example from the STAC plugin
const layerId = store.addGeoJsonLayer(labels.footprintLayerName, geojson);

STAC Plugin Example

// Add a remote STAC asset via the STAC plugin
import { useAppStore } from '@geolibre/core';
import { fetchStacItem } from '@geolibre/plugins';

async function addStacAsset(url: string) {
  const { geojson } = await fetchStacItem(url);
  useAppStore.getState().addGeoJsonLayer('STAC Footprint', geojson);
}

Persistence and Project Files

GeoLibre projects serialize layer state for reproducibility.

.geolibre.json Format

Projects are stored as .geolibre.json files per docs/project-format.md. When saving, the store's layer list—including source paths—is serialized, enabling reload without re-importing raw data.

Project Persistence Example

// Persist a project (frontend)
import { saveProject } from '@geolibre/core';

const json = saveProject();               // returns .geolibre.json content
download('my-project.geolibre', json);    // invoke a browser download

Key Implementation Files

Path Role
packages/core/src/store.ts Central Zustand store where every layer is recorded
packages/plugins/src/types.ts Public API surface—defines addGeoJsonLayer and helpers
packages/plugins/src/plugins/maplibre-stac.ts Plugin loading external files via core API
backend/geolibre_server/app/conversion.py Server-side conversion for heavy formats
apps/geolibre-desktop/src/hooks/usePlugins.ts Registers built-in plugins and wires to store
docs/project-format.md Specification for .geolibre.json project files

Summary

  • Centralized state: All layers live in packages/core/src/store.ts via Zustand
  • Unified API: addGeoJsonLayer in packages/plugins/src/types.ts is the entry point for all vector data
  • Dual-path ingestion: Browser handles light formats via DuckDB-WASM; heavy formats route through FastAPI side-car
  • Plugin compatibility: External services integrate through the same API surface
  • Project portability: .geolibre.json files serialize layer metadata for reproducible sessions

Frequently Asked Questions

How does GeoLibre handle large raster files that won't fit in browser memory?

GeoLibre delegates to a FastAPI side-car (backend/geolibre_server). The client uploads via /raster endpoint, the server converts to MBTiles or COG, and returns a reference that addRasterLayer consumes. This keeps the UI responsive while processing occurs server-side.

Can custom plugins add files from proprietary APIs?

Yes. Plugins implement the interface in packages/plugins/src/types.ts and call store.addGeoJsonLayer with their fetched data. The STAC plugin (maplibre-stac.ts) demonstrates this pattern—extract assets, convert to GeoJSON, and register through the core API.

What happens to file paths when a project is shared?

The .geolibre.json format stores source paths relative to the project root where possible. Absolute paths are preserved for side-car references. Recipients must ensure referenced files are accessible at those paths, or GeoLibre will prompt for re-location on project open.

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 →