How to Build and Deploy GeoLibre as a Progressive Web App

Build GeoLibre as a Progressive Web App by running npm run build in the monorepo root, which generates a web-ready bundle with a Web App Manifest and Workbox service worker in apps/geolibre-desktop/dist, ready for static hosting.

GeoLibre is an open-source geospatial analysis platform that can be distributed as a Progressive Web App (PWA) to enable offline functionality and native-like installation without the desktop shell. When you build and deploy GeoLibre as a Progressive Web App, you create a browser-based bundle that caches heavy client-side engines like DuckDB-WASM and Pyodide for offline use. The build process leverages Vite and vite-plugin-pwa to automate service worker generation and asset precaching according to the configuration in apps/geolibre-desktop/vite.config.ts.

Prerequisites

Before building the PWA, ensure your environment meets the following requirements:

  • Node.js ≥ 22 and npm – The GeoLibre monorepo uses npm workspaces and relies on recent Node.js features for build scripts defined in package.json.
  • Git – Required to clone the repository.
  • Docker (optional) – For creating a production-ready nginx image that serves the static PWA files.

Clone and Install Dependencies

GeoLibre is structured as a single npm workspaces monorepo containing apps/*, packages/*, and workers/* directories. Install all dependencies in one pass:

git clone https://github.com/opengeos/GeoLibre.git
cd GeoLibre
npm ci

The npm ci command respects the lockfile and wires up every workspace automatically, preparing the React UI and build toolchain.

Build the PWA Bundle

Generate the production PWA bundle using the standard build command:

npm run build

This command executes vite build configured for the web target in apps/geolibre-desktop/vite.config.ts. The build process:

  1. Compiles the React UI application located in apps/geolibre-desktop.
  2. Generates the Web App Manifest (manifest.webmanifest) and Workbox service worker (sw.js) via vite-plugin-pwa.
  3. Outputs static assets to apps/geolibre-desktop/dist/.

According to the source code in apps/geolibre-desktop/vite.config.ts, the PWA plugin configures caching strategies for the app shell and runtime assets, while the architecture documentation in docs/architecture.md specifies that the service worker precaches the core application shell and implements runtime caching for heavy engines.

Verify PWA Assets

After the build completes, confirm the presence of required PWA files in the output directory:


apps/geolibre-desktop/dist/
├── index.html
├── assets/                 # Hashed JavaScript and CSS chunks

├── manifest.webmanifest    # Web App Manifest

├── sw.js                   # Workbox service worker

└── ...

You can verify service worker registration by running this JavaScript in the browser console after serving the dist folder:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.getRegistration().then(reg => console.log('SW registered:', reg));
}

The service worker is intentionally bundled only for the web build; the Tauri desktop build disables it since native apps already ship offline assets.

Deploy the PWA

The dist/ directory contains static files compatible with any static-file host. Choose one of the following deployment methods:

Static File Hosting

Serve the dist/ folder using any basic web server:

cd apps/geolibre-desktop/dist
python -m http.server 8080

Visit http://localhost:8080 in a PWA-compatible browser to trigger the "Add to Home screen" prompt.

Docker Production Image

The repository includes a Dockerfile that builds the web bundle and wraps it in an nginx container. This configuration copies apps/geolibre-desktop/dist into the image and sets up fallback routing to index.html for single-page application (SPA) navigation:

docker build -t geolibre-pwa .
docker run -d -p 80:80 geolibre-pwa

As implemented in the Dockerfile, nginx serves the PWA on port 80 with proper MIME types for the service worker and manifest files.

Cloud Platforms

Deploy to serverless hosting platforms by configuring the build command and publish directory:

  • Cloudflare Pages or Netlify: Set build command to npm run build and publish directory to apps/geolibre-desktop/dist.
  • GitHub Pages: Push the contents of dist/ to a gh-pages branch or use GitHub Actions to automate the build and deploy pipeline.

Enable Full Offline Support

By default, the service worker precaches the app shell (HTML, core JS/CSS) and runtime-caches heavy engines (DuckDB-WASM, Pyodide, PGlite, CereusDB) after their first network fetch. To embed these engines directly in the bundle for immediate offline availability without a CDN, set environment variables before building:

GEOLIBRE_PGLITE_CDN=0 GEOLIBRE_CEREUS_CDN=0 npm run build

These flags store the engines under /assets/, allowing the Workbox service worker to cache them during the initial install event. Refer to the "Offline support (PWA)" section in docs/architecture.md for the complete caching strategy details.

Summary

  • Install dependencies with npm ci in the monorepo root to prepare the workspace.
  • Build the PWA by running npm run build, which outputs manifest.webmanifest and sw.js to apps/geolibre-desktop/dist/ via the Vite configuration.
  • Deploy the static dist/ folder using nginx (via the provided Dockerfile), Cloudflare Pages, GitHub Pages, or any static host.
  • Optimize offline capability by setting GEOLIBRE_PGLITE_CDN=0 and GEOLIBRE_CEREUS_CDN=0 to embed heavy engines for precaching.

Frequently Asked Questions

What is the difference between the GeoLibre desktop app and the PWA version?

The desktop app uses Tauri to wrap the web interface in a native OS shell, while the PWA version runs entirely in the browser using a service worker for offline functionality. Both share the same React codebase, but the PWA is served as static files from apps/geolibre-desktop/dist and installs through the browser, whereas the desktop app downloads a native executable.

Why does the service worker not appear in the desktop build?

The Tauri desktop configuration intentionally disables the service worker because the application assets are already bundled locally with the executable. According to the build logic in apps/geolibre-desktop/vite.config.ts, the service worker is only injected for web targets where offline caching is necessary.

Can I customize the PWA manifest and icons?

Yes, modify the PWA configuration in apps/geolibre-desktop/vite.config.ts where vite-plugin-pwa accepts options for the manifest path, theme colors, icon sizes, and caching strategies. After updating, rebuild with npm run build to regenerate manifest.webmanifest with your customizations.

How do I update the PWA when deploying a new version?

The Workbox service worker generated by vite-plugin-pwa handles updates automatically by precaching new assets and activating a new service worker in the background. Users will see the updated application on the next visit after the new dist/ files are deployed, as the browser detects changes to sw.js and the asset hashes in the precache manifest.

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 →