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 version strings to current schema.
  • Default injection: Fills missing optional fields (metadata, style, etc.).
  • UUID validation: Ensures all layer IDs are valid UUIDs.
  • Source reconstruction: Rebuilds source objects 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.json stores complete GeoLibre projects as flat JSON with a versioned, extensible schema.
  • Top-level fields cover workspace state: mapView, layers, styles, plugins, legend, storymap, widgets, and metadata.
  • serializeProject outputs pretty-printed JSON via standard JSON.stringify—no proprietary encoding.
  • parseProject normalizes 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 source and 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:

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 →