Contributing¶
Thanks for your interest in improving GeoLibre. This guide covers how to set up a development environment, the project layout, the local quality gate, and the pull request workflow. Contributions of all sizes are welcome, from fixing a typo to adding a new processing tool or plugin.
By participating, you agree to keep interactions respectful and constructive.
Ways to contribute¶
- Report a bug or request a feature by opening an issue. Include steps to reproduce, what you expected, and what happened, plus your OS and whether you hit it in the web or desktop build.
- Improve the documentation under
docs/(this site). - Fix a bug or build a feature in the app or one of the packages.
- Write a plugin using the external plugin API (see Plugins below).
If you plan a large change, open an issue first so we can agree on the approach before you invest time in a pull request.
Prerequisites¶
- Node.js 22 or newer
- Rust toolchain (rustup) for Tauri desktop builds
- Linux only:
webkit2gtkandlibayatana-appindicator(see the Tauri prerequisites) - Python 3.10 or newer for pre-commit (the commit hooks below) and, if you work on the backend, the conversion sidecar and its tests
Set up¶
git clone https://github.com/opengeos/GeoLibre.git
cd GeoLibre
npm install
GeoLibre is an npm workspaces monorepo, so a single npm install at the root
wires up every package. Use npm; the repository tracks package-lock.json.
Run it locally¶
Web build (map in the browser):
npm run dev
Open http://localhost:5173.
Desktop build (Tauri, required for filesystem dialogs, local MBTiles, and local raster reads):
npm run tauri:dev
Repository layout¶
apps/geolibre-desktop # Tauri + React app (shell, composition, Tauri I/O)
packages/core # Domain types, Zustand store, project format
packages/map # MapLibre integration and layer sync
packages/ui # Tailwind + shadcn/ui primitives
packages/plugins # Plugin API and built-in plugins
packages/processing # Client-side algorithm registry
workers/viewer # Cloudflare viewer worker (geolibre-viewer-worker)
backend/geolibre_server # Optional FastAPI conversion sidecar (Python)
sample-data/ # Sample GeoJSON and an example project
docs/ # This documentation site (MkDocs)
See the Architecture reference for how these fit together, and the Project Format reference for the saved project schema.
Development workflow¶
-
Create a feature branch off
main. Never commit directly tomain.git switch -c feat/short-description -
Make your change, keeping it focused. Match the style of the surrounding code rather than introducing new patterns.
- Run the quality checks and confirm they pass.
- Commit with a clear message. The history follows a
Conventional Commits style prefix,
for example
feat:,fix:,docs:,refactor:, orchore:. - Push your branch and open a pull request against
main. Describe what changed and why, and link any related issue.
Pull requests are reviewed before merging. Automated reviewers may leave inline comments; address them or explain why a suggestion does not apply.
Quality checks¶
Run the fast TypeScript unit tests while you work:
npm run test:frontend
Before opening a pull request, run the formatting hooks and the full local quality gate:
pre-commit run --all-files
npm run ci
npm run ci runs the complete gate that mirrors continuous integration:
| Step | Command | Covers |
|---|---|---|
| Build | npm run build |
TypeScript compile and Vite build |
| Frontend tests | npm run test:frontend |
Fast unit tests under tests/ |
| Worker typecheck | npm run test:worker |
The viewer worker package |
| Backend tests | npm run test:backend |
pytest for the Python sidecar |
| Rust check | npm run check:rust |
cargo check for the Tauri shell |
You only need the toolchains for the areas you touched. A docs-only or
frontend-only change does not require Rust or Python, though the full npm run
ci gate does.
Coding conventions¶
- The pre-commit hooks enforce TypeScript compile errors (
npm run build), LF line endings (mixed-line-ending --fix=lf), and basic whitespace (the end-of-file and trailing-whitespace fixers). There is no Prettier or ESLint hook, so match the style of the surrounding code and fix any build errors the hooks surface before committing. - Do not edit files in
node_modules. If a third-party MapLibre control needs app-specific styling, add a scoped override inapps/geolibre-desktop/src/index.csslimited to that control's class. - Keep changes scoped to the package they belong to, and prefer reusing the
shared primitives in
packages/uiand helpers inpackages/core.
Documentation¶
The site is built with MkDocs Material. To preview your changes locally:
python -m pip install -r requirements-docs.txt
mkdocs serve
Open http://localhost:8000. When you add a new page, add it to the nav in
mkdocs.yml. The site is built with mkdocs build --strict in CI, so broken
links and pages left out of the navigation fail the build. Link to other docs
pages with a relative path (for example architecture.md), and link to files
outside docs/ with a full GitHub URL.
Plugins and extensions¶
GeoLibre supports external plugins loaded from a zip, a local directory, or a hosted manifest URL. To build one, start from the GeoLibre plugin template and follow the Plugin API contract. You do not need to fork GeoLibre itself to ship a plugin.
Backend sidecar¶
The optional FastAPI sidecar
powers the server-side conversion tools. The conversion extra installs the
conversion runtime (DuckDB, rio-cogeo, and friends) and the dev extra installs
the test runner, so install both when working on it:
cd backend/geolibre_server
python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[conversion,dev]"
geolibre-server
For a base, conversion-free run (pip install -e . plus a plain uvicorn
launch), see the sidecar README.
Run its tests with npm run test:backend from the repository root, or
python -m pytest from the backend directory.
License¶
GeoLibre is released under the MIT License. By contributing, you agree that your contributions are licensed under the same terms.