GeoLibre File Listing Methods: A Complete Guide to Local and Remote Data Discovery

GeoLibre uses a layered, security-first approach to file listing that combines browser-native file pickers, allow-listed remote fetching, plugin-based discovery, and DuckDB-WASM-powered format conversion.

GeoLibre (Geospatial Libre) is a polyglot, store-driven GIS application that ingests vector, raster, and tile data from diverse sources. Understanding how GeoLibre file listing methods work is essential for developers extending the platform or users optimizing their data workflows.

Core Architecture of GeoLibre File Listing

The file listing system spans five distinct layers, each with a specific responsibility and security boundary.

Layer Responsibility Implementation
UI Layer (React) Exposes file picker, drag-and-drop, and remote browse interfaces Native <input type="file" multiple/> and HTML5 drag events
Store Layer (@geolibre/core) Maintains Zustand collection of GeoLibreLayer objects packages/core/src/store.ts
Client-Side Converter Transforms unsupported formats to GeoJSON using DuckDB-WASM Spatial ST_Read SQL function via duckdb-wasm
Remote Fetch Worker Retrieves remote datasets from allow-listed origins only workers/tiles/src/allowlisted-fetch.ts
Plugin Registry Dynamically discovers and loads built-in file providers apps/geolibre-desktop/vite-plugins/bundled-plugins.ts

All remote file operations pass through fetchAllowlistedUpstream, which validates HTTPS scheme, host, and exact path prefix before executing any network request.

Local File Listing Methods

Browser Native File Picker

GeoLibre leverages standard browser APIs for local file selection. The picker filters by supported extensions maintained in core package constants.

// Component implementing GeoLibre file listing for local files
function FileUploader() {
  const handleFiles = async (files: FileList) => {
    for (const file of files) {
      const geojson = await convertIfNeeded(file); // DuckDB-WASM conversion
      addGeoJsonLayer(geojson);                    // Store update
    }
  };

  return (
    <input
      type="file"
      multiple
      accept={SUPPORTED_EXTENSIONS.join(',')}
      onChange={e => e.target.files && handleFiles(e.target.files)}
    />
  );
}

Drag-and-Drop File Discovery

The drop zone listens for dragover and drop events, extracting FileList from the data transfer object. This provides identical functionality to the picker without modal interaction.

DuckDB-WASM Format Conversion

When users select non-native formats (Shapefile, KMZ, GeoParquet), the client-side converter passes files to DuckDB-WASM Spatial's ST_Read function. This runs entirely in the browser without server round-trips.

Remote File Listing with Allow-List Protection

Fetch Security Model

The fetchAllowlistedUpstream function in workers/tiles/src/allowlisted-fetch.ts implements GeoLibre's security boundary for remote data. It enforces:

  • HTTPS scheme requirement
  • Exact host allow-list matching
  • Path prefix validation
  • Redirect chain inspection (rejections for off-list destinations)
// workers/tiles/src/allowlisted-fetch.ts
import { fetchAllowlistedUpstream } from "./allowlisted-fetch";

export async function fetchGeoParquet(url: string) {
  const upstream = new URL(url);
  // Only allow-listed host + path prefixes permitted
  const response = await fetchAllowlistedUpstream(upstream.toString());
  return response.arrayBuffer();
}

Supported Remote Registries

GeoLibre's Add Data dialog provides built-in browsing for:

  • Source Cooperative — community geospatial data portal
  • Hugging Face — ML-ready geospatial datasets
  • OpenAerialMap — drone and satellite imagery

Each registry uses pre-configured allow-list entries that map UI queries to validated fetchAllowlistedUpstream calls.

Plugin-Based File Source Discovery

Bundled plugins extend GeoLibre file listing capabilities by declaring fileTypes arrays. The build system discovers these plugins at compile time.

// apps/geolibre-desktop/vite-plugins/bundled-plugins.ts
import { existsSync, readdirSync, statSync } from "node:fs";

export function listBundledPlugins(pluginsDir: string) {
  if (!existsSync(pluginsDir)) return [];
  return readdirSync(pluginsDir)
    .filter(name => statSync(`${pluginsDir}/${name}`).isDirectory());
}

This function runs during Vite bundling, generating a static plugin manifest that the runtime uses to populate file type filters and source options.

Test Fixture Enumeration

The test suite validates format support by enumerating fixture files using Node.js filesystem APIs.

// tests/vector-golden.test.ts
import { readdirSync } from "node:fs";

const CASES_DIR = "tests/fixtures/vector-golden";
const files = readdirSync(CASES_DIR).filter(f => f.endsWith(".json"));

This pattern ensures comprehensive coverage across all supported vector formats without manual test registration.

Key Source Files for GeoLibre File Listing

File Role Source Link
workers/tiles/src/allowlisted-fetch.ts Validates and fetches remote URLs against security allow-list view source
apps/geolibre-desktop/vite-plugins/bundled-plugins.ts Scans plugins/ directory for bundled plugins at build time view source
tests/vector-golden.test.ts Uses readdirSync to enumerate JSON fixtures for vector format tests view source
packages/core/src/store.ts Defines Zustand store holding GeoLibreLayer collection view source
packages/map/src/add-layer.ts Implements addGeoJsonLayer entry point for file loading view source
docs/user-guide/adding-data.md User-facing documentation for Add Data UI and supported formats view source

Summary

Frequently Asked Questions

How does GeoLibre handle unsupported file formats?

GeoLibre passes unsupported vector formats (Shapefile, KMZ, GeoParquet) to DuckDB-WASM Spatial's ST_Read function, which converts them to GeoJSON entirely in the browser. This eliminates server dependencies while maintaining broad format support.

Can GeoLibre fetch data from any HTTPS URL?

No. All remote requests route through fetchAllowlistedUpstream, which validates URLs against a strict allow-list of hosts and path prefixes. This prevents open-proxy vulnerabilities while enabling access to trusted registries like Source Cooperative and Hugging Face.

Where are active file layers stored in GeoLibre?

Loaded layers exist as GeoLibreLayer objects in a Zustand store defined in packages/core/src/store.ts. The addGeoJsonLayer function in packages/map/src/add-layer.ts creates these records when files complete processing.

How do plugins add new file listing capabilities?

Plugins declare supported fileTypes in their metadata. The build process calls listBundledPlugins to discover these declarations, and the runtime uses them to populate extension filters and remote source options in the Add Data dialog.

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 →