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:
- Generates a unique layer ID
- Inserts a new GeoLibreLayer entry into the store
- Seeds the layer with
DEFAULT_LAYER_STYLEfor 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:
packages/plugins/src/plugins/maplibre-open-data-catalogs.ts— adds remote datasets as GeoJSON layers at line 287packages/plugins/src/plugins/maplibre-stac.ts— extracts STAC assets and callsstore.addGeoJsonLayerat line 462
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.tsvia Zustand - Unified API:
addGeoJsonLayerinpackages/plugins/src/types.tsis 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.jsonfiles 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →