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
- GeoLibre file listing methods combine browser-native APIs, DuckDB-WASM conversion, and strict allow-list remote fetching.
- Local files use
<input type="file">and drag-and-drop with format conversion handled client-side. - Remote sources pass through
fetchAllowlistedUpstreaminworkers/tiles/src/allowlisted-fetch.tsfor security validation. - Plugin discovery via
listBundledPluginsinapps/geolibre-desktop/vite-plugins/bundled-plugins.tsenables extensible file source registration. - Test fixtures use
readdirSyncpattern intests/vector-golden.test.tsfor automated format coverage.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →