GeoLibre Repository File Browsing Techniques: A Complete Technical Guide

GeoLibre uses a workspace-driven monorepo architecture with clear separation between apps, packages, workers, and backend services, where file browsing flows through Tauri dialogs or browser pickers, URL sanitization via a viewer proxy, and state management through a Zustand store before syncing to MapLibre.

The opengeos/GeoLibre repository implements a sophisticated multi-environment file browsing system designed to work identically across web, desktop (Electron/Tauri), and Jupyter environments. Understanding its layout and data flow is essential for contributors extending data import functionality or debugging layer loading issues.

GeoLibre Monorepo Structure

GeoLibre organizes code into five logical groups under a single NPM workspaces configuration:

Group Location Primary Responsibility
Apps apps/* Desktop wrapper (geolibre-desktop) and web front-end
Packages packages/* Core libraries including @geolibre/core, @geolibre/map, @geolibre/ui, @geolibre/processing, @geolibre/plugins, and @geolibre/embed
Workers workers/* Background services: viewer, tile server, collaboration, and AI proxy
Backend backend/geolibre_server Optional FastAPI sidecar for heavy-weight processing
Python / R python/ & r/ Jupyter-compatible Python package and R package

The root package.json wires these workspaces together. This configuration is your starting point for any file browsing exploration.

Key Entry Points for File Browsing

Several files serve as critical navigation landmarks when tracing how GeoLibre handles file operations:

Workspace Configuration

The root package.json defines the workspace layout and lists all sub-packages with their dependencies:

{
  "name": "geolibre",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*",
    "workers/*"
  ]
}

Architecture Documentation

docs/architecture.md provides a high-level diagram showing how UI components, the Zustand store, map controller, and workers interact during file operations.

Core Implementation Files

File Path Purpose
packages/core/src/store.ts Zustand store holding canonical project state (.geolibre.json)
packages/map/src/map-controller.ts MapLibre-GL controller that syncs layer definitions from store to map
apps/geolibre-desktop/src-tauri Tauri native layer bridging UI with host OS file dialogs
workers/viewer/src/proxy.ts URL path validation before viewer worker fetches
tests/vector-url-fetch.test.ts Integration tests for file-browsing pipeline

The File Browsing Workflow

GeoLibre processes file imports through a seven-step pipeline that maintains security and consistency across deployment targets.

Step 1: User Initiates File Add

Users trigger imports via Add Data menu, drag-and-drop, or plugin controls.

Step 2: Path Acquisition

The UI obtains file paths through environment-specific dialogs:

Step 3: Security Validation

The viewer proxy (workers/viewer/src/proxy.ts) sanitizes all paths before fetching. It rejects relative-segment attacks (..) and malformed URLs.

// Manual proxy sanitization test
import { sanitizeUrl } from "workers/viewer/src/proxy";

const unsafe = "/foo%2f..%2fsecret";
console.log(sanitizeUrl(unsafe)); // Throws or returns safe URL

Step 4: File Parsing

Processing depends on file type:

File Type Handler Location
Local vector DuckDB-WASM packages/processing
Raster/remote service Plugin system @geolibre/plugins

Step 5: Store Update

Helpers like addGeoJsonLayer write new layers to the Zustand store:

import { addGeoJsonLayer } from "@geolibre/core";
import { readFileSync } from "node:fs";

const geojson = JSON.parse(readFileSync("examples/sample.geojson", "utf8"));

addGeoJsonLayer({
  id: "sample",
  source: { type: "geojson", data: geojson },
  paint: { 
    "fill-color": "#ff6600", 
    "fill-opacity": 0.5 
  },
});

Step 6: Map Synchronization

MapController.syncLayers (packages/map/src/map-controller.ts) translates store records into MapLibre source/layer objects and injects them into the canvas.

Step 7: Optional Backend Processing

For heavy conversion or AI tools, requests forward to the FastAPI sidecar at http://127.0.0.1:8765 (backend/geolibre_server).

Practical Exploration Code

List all workspace packages to understand repository topology:

import { readFileSync } from "node:fs";
import { resolve } from "node:path";

const pkg = JSON.parse(readFileSync(resolve("package.json"), "utf8"));
console.log("Workspaces:", pkg.workspaces);
// Output: [ 'apps/*', 'packages/*', 'workers/*' ]

List critical file-browsing source files:


# Find all store-related files

find packages/core -name "*.ts" | grep -E "(store|layer)"

# Locate proxy implementation

ls workers/viewer/src/proxy.ts

# Examine test coverage

ls tests/vector-url-fetch.test.ts tests/share-readiness.test.ts

Security Implementation Details

The workers/viewer/src/proxy.ts file serves as the security gatekeeper for all external file references. Its sanitizeUrl function:

  • Decodes URL-encoded characters
  • Validates against path traversal patterns
  • Enforces allowlist-based domain restrictions for remote URLs

This proxy runs in an isolated worker thread, preventing main-thread blocking during validation.

Testing File Browsing Behavior

The tests/ directory contains extensive validation:

Tests guarantee identical behavior across web, desktop, and Jupyter environments.

Summary

Frequently Asked Questions

How do I add a new file format handler to GeoLibre?

Create a plugin in packages/ following the @geolibre/plugins pattern. Register your format detector in the plugin's index.ts, then implement the parser using either DuckDB-WASM for tabular data or custom loaders for binary formats. Add integration tests in tests/ mirroring vector-url-fetch.test.ts.

Why does GeoLibre use a proxy worker for file URLs?

The viewer proxy (workers/viewer/src/proxy.ts) isolates URL validation from the main thread for both security and performance. It prevents path traversal attacks, enforces domain allowlists, and avoids blocking the UI during network requests. Running in a worker enables concurrent validation of multiple sources.

Where is the canonical project state stored in GeoLibre?

The Zustand store in packages/core/src/store.ts holds the single source of truth as a .geolibre.json structure. All file imports eventually write layer records here, and MapController.syncLayers subscribes to these changes to update the visualization.

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 →