GeoLibre `.geolibre.json` Project Format Schema and Serialization Guide
The .geolibre.json format is a JSON-based project file that stores the complete GeoLibre workspace state, serialized via JSON.stringify with optional pretty-printing and parsed back through parseProject with automatic normalization and validation.
GeoLibre uses a single file to persist entire mapping projects—layers, styles, camera position, plugins, and dashboard widgets. Understanding the .geolibre.json schema and serialization API is essential for building integrations, automating workflows, or manipulating projects programmatically. This guide covers the complete schema structure and the serialization helpers implemented in the core package.
Top-Level Schema Structure
A .geolibre.json file contains a flat JSON object with the following fields. Optional sections are omitted when empty to minimize file size.
| Field | Type | Description |
|---|---|---|
version |
string | Project format version, e.g., "0.1.0". |
name |
string | Human-readable project title. |
mapView |
object | Camera state: center (lng,lat), zoom, bearing, pitch, and optional bbox. |
basemapStyleUrl |
string | URL to a MapLibre style JSON; empty string means blank background. |
basemapVisible |
boolean | Whether the background layer renders. |
basemapOpacity |
number (0–1) | Opacity of the background layer. |
layers |
array | Ordered list of layer objects (see Layer Object section below). |
styles |
object | Map of layer IDs to LayerStyle definitions. |
plugins |
object (optional) | Plugin manifests, active IDs, UI positions, and settings. |
legend |
object (optional) | Print-layout legend customizations: title, ordering, per-item overrides. |
storymap |
object (optional) | Scroll-driven narrative with chapters and map animations. |
widgets |
array (optional) | Dashboard chart widgets: histogram, bar, scatter, etc. |
dashboardColumns |
number (optional) | Grid columns for dashboard (1–6, default 2). |
styleLibrary |
array (optional) | Project-scoped style manager entries. |
metadata |
object | Free-form key/value pairs for custom data. |
The authoritative documentation lives in [docs/project-format.md](https://github.com/opengeos/GeoLibre/blob/main/docs/project-format.md) in the source repository.
Layer Object Schema
Each entry in the layers array follows a unified structure. The type field determines how source and data properties are interpreted.
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Buildings",
"type": "geojson",
"source": { "type": "geojson" },
"visible": true,
"opacity": 1,
"style": {
"minZoom": 0,
"maxZoom": 24,
"fillColor": "#3b82f6",
"strokeColor": "#1e40af",
"strokeWidth": 2,
"strokeWidthUnit": "pixels",
"fillOpacity": 0.6,
"circleRadius": 6,
"rasterBrightnessMin": 0,
"rasterBrightnessMax": 1,
"rasterSaturation": 0,
"rasterContrast": 0,
"rasterHueRotate": 0
},
"metadata": {},
"geojson": {
"type": "FeatureCollection",
"features": []
},
"sourcePath": "/data/buildings.geojson"
}
Supported type values include: geojson, xyz, wms, vector-tiles, mbtiles, cog, zarr, and 3d-tiles. Raster-specific style properties are ignored for vector layers and vice versa.
How GeoLibre Serializes Projects
Serialization and deserialization are handled by three core functions in @geolibre/core. The implementation is intentionally thin—projects are plain JSON objects.
import {
createEmptyProject,
parseProject,
serializeProject,
} from "@geolibre/core";
// 1. Create or modify a project
const project = createEmptyProject("My Analysis");
// 2. Serialize to formatted JSON string
const json = serializeProject(project);
// Internally: JSON.stringify(project, null, 2)
// Source: packages/core/src/project.ts lines 109-111
// 3. Parse back with validation and normalization
const restored = parseProject(json);
serializeProject Implementation
In [packages/core/src/project.ts](https://github.com/opengeos/GeoLibre/blob/main/packages/core/src/project.ts#L109-L111), the function is defined as:
export function serializeProject(project: GeoLibreProject): string {
return JSON.stringify(project, null, 2);
}
The null, 2 arguments enable two-space indentation for human readability. No custom encoding or binary transformation occurs—any language with JSON support can produce or consume .geolibre.json files.
parseProject Normalization Pipeline
parseProject performs several safety steps when loading hand-edited or legacy files:
- Version migration: Upgrades old
versionstrings to current schema. - Default injection: Fills missing optional fields (
metadata,style, etc.). - UUID validation: Ensures all layer IDs are valid UUIDs.
- Source reconstruction: Rebuilds
sourceobjects from shorthand properties.
This pipeline protects downstream code from malformed inputs without rejecting valid JSON.
Working with .geolibre.json Programmatically
Create and Save a New Project
import { createEmptyProject, serializeProject } from "@geolibre/core";
import { writeFile } from "fs/promises";
async function saveNewProject() {
const project = createEmptyProject("Demo Project");
const json = serializeProject(project);
await writeFile("demo.geolibre.json", json);
}
saveNewProject();
Load and Inspect an Existing Project
import { readFile } from "fs/promises";
import { parseProject } from "@geolibre/core";
async function loadProject(path: string) {
const json = await readFile(path, "utf-8");
const project = parseProject(json);
console.log(`Loaded: ${project.name} with ${project.layers.length} layers`);
}
loadProject("demo.geolibre.json");
Add a GeoJSON Layer and Serialize
import { createEmptyProject, serializeProject } from "@geolibre/core";
import { v4 as uuid } from "uuid";
const project = createEmptyProject("With Layer");
project.layers.push({
id: uuid(),
name: "Sensor Locations",
type: "geojson",
source: { type: "geojson" },
visible: true,
opacity: 0.9,
style: {
circleRadius: 8,
fillColor: "#ef4444",
strokeColor: "#991b1b",
strokeWidth: 1
},
metadata: { department: "Environmental" },
geojson: {
type: "FeatureCollection",
features: []
}
});
const output = serializeProject(project);
console.log(output);
Cross-Language Interoperability
Because .geolibre.json is pure JSON, Python, Rust, and other ecosystems can manipulate projects without native GeoLibre bindings. The Python sidecar demonstrates this pattern:
import geolibre
m = geolibre.Map()
m.add_geojson("data.geojson")
m.save_project("output.geolibre.json") # Writes identical JSON structure
See [python/README.md](https://github.com/opengeos/GeoLibre/blob/main/python/README.md) for the full Python API.
Key Source Files
| File | Purpose |
|---|---|
[docs/project-format.md](https://github.com/opengeos/GeoLibre/blob/main/docs/project-format.md) |
Human-readable schema specification for all fields and layer types. |
[packages/core/src/project.ts](https://github.com/opengeos/GeoLibre/blob/main/packages/core/src/project.ts) |
serializeProject, parseProject, and validation logic. |
[packages/core/src/types.ts](https://github.com/opengeos/GeoLibre/blob/main/packages/core/src/types.ts) |
TypeScript definitions: GeoLibreProject, Layer, LayerStyle, PluginState. |
[apps/geolibre-desktop/src/lib/tauri-io.ts](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/lib/tauri-io.ts) |
Desktop file I/O using Tauri's filesystem API. |
Summary
.geolibre.jsonstores complete GeoLibre projects as flat JSON with a versioned, extensible schema.- Top-level fields cover workspace state:
mapView,layers,styles,plugins,legend,storymap,widgets, andmetadata. serializeProjectoutputs pretty-printed JSON via standardJSON.stringify—no proprietary encoding.parseProjectnormalizes and validates on load, enabling robust handling of hand-edited or legacy files.- Layer objects unify heterogeneous data sources under a common structure with typed
sourceand optional data embedding.
Frequently Asked Questions
What is the current version of the .geolibre.json format?
The current version is "0.1.0". The version field in the top-level object enables forward migration through parseProject. Future releases will increment this string and include automated upgrade paths.
Can I edit .geolibre.json files by hand?
Yes. Because the format is plain JSON, any text editor or programmatic tool can modify projects. parseProject validates and normalizes on load, so minor omissions like missing metadata or partial style objects are automatically repaired.
How do I add custom data to a project?
Use the metadata object at the top level or on individual layers. This free-form key/value map accepts any JSON-serializable data and is preserved through load/save cycles without schema enforcement.
Does GeoLibre support binary or compressed project formats?
Not natively. serializeProject outputs uncompressed UTF-8 JSON. For large projects with embedded GeoJSON, standard file-system compression (gzip, zstd) can be applied externally. The desktop app handles this transparently when saving to .geolibre.json.gz extensions.
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 →