# Service Worker Cache Strategy for Offline CDN Engines in GeoLibre

> Discover GeoLibre's service worker cache strategy. Learn how CacheFirst ensures offline CDN engine functionality for seamless GeoLibre access after initial download.

- Repository: [Open Geospatial Solutions/GeoLibre](https://github.com/opengeos/GeoLibre)
- Tags: internals
- Published: 2026-08-22

---

**GeoLibre uses a Workbox-generated service worker with a CacheFirst strategy to store CDN-hosted computation engines locally, enabling full offline functionality after the first download.**

GeoLibre’s web build functions as a **Progressive Web App (PWA)** that must operate reliably without network connectivity. Because the application relies on heavy **WebAssembly engines**—including Pyodide, PGlite/PostGIS, CereusDB Sedona Wasm, gdal3.js, and DuckDB-WASM—served from external CDNs, the project implements a specialized runtime caching layer to ensure these resources remain available offline. The strategy is defined in the Workbox configuration and architecture documentation within the `opengeos/GeoLibre` repository.

## Three-Tier Caching Architecture

The service worker generated by `vite-plugin-pwa` implements three distinct caching layers to balance application shell stability with dynamic asset storage:

- **Pre-cache (App Shell):** Stores the HTML and initial JavaScript/CSS chunks required to bootstrap the map interface. These assets are precached during the service worker installation, guaranteeing the application shell loads without any network connection after the first visit.

- **Runtime Cache – Assets:** Handles build assets under `/assets/` (e.g., the MapLibre bundle, DuckDB-WASM spatial extensions, and feature-plugin chunks). These same-origin, content-hashed files are stored using a `CacheFirst` strategy under the `geolibre-assets` cache.

- **Runtime Cache – CDN Engines:** Dedicated to heavy computation engines loaded from `cdn.jsdelivr.net`. This layer uses the **`geolibre-cdn-engines`** cache with a `CacheFirst` strategy to intercept and store responses for engine URLs.

## How CDN Engine Caching Works

As documented in [`docs/architecture.md`](https://github.com/opengeos/GeoLibre/blob/main/docs/architecture.md) (lines 95-102), the CDN engine cache specifically targets high-bandwidth WebAssembly modules that would otherwise fail to load in offline scenarios. The service worker registers a runtime route that matches requests to `cdn.jsdelivr.net` and stores successful 200 OK responses for subsequent offline use.

### CacheFirst Strategy Implementation

The `geolibre-cdn-engines` cache employs a **CacheFirst** strategy, meaning the service worker always attempts to serve the engine from the local cache before checking the network. This approach serves two purposes: it eliminates redundant downloads when connectivity is present, and it guarantees deterministic offline behavior when the network is unavailable.

The strategy applies to specific engine URLs:
- Pyodide packages (e.g., `https://cdn.jsdelivr.net/npm/pyodide@0.26.1/...`)
- PGlite/PostGIS builds
- CereusDB Sedona Wasm
- gdal3.js distributions
- DuckDB-WASM when served from jsDelivr (when `GEOLIBRE_DUCKDB_WASM_CDN=1`)

### Version-Bound URL Safety

A critical safety mechanism prevents stale engine versions from persisting in the cache. Because the CDN URLs embed exact package version numbers (e.g., `@0.26.1`), a new deployment automatically generates new request URLs. The CacheFirst rule therefore never serves outdated engine versions—each version upgrade creates a distinct cache entry, while old versions naturally expire based on the cache quota.

## Configuring Local vs CDN Engine Loading

GeoLibre provides environment flags that bypass the CDN caching strategy entirely by bundling engines locally:

- **`GEOLIBRE_PGLITE_CDN=0`** – Bundles PGlite/PostGIS under `/assets/`, causing the engine to be captured by the standard assets CacheFirst rule instead of the CDN-specific cache.

- **`GEOLIBRE_CEREUS_CDN=0`** – Forces local bundling of the CereusDB engine, moving it from the `geolibre-cdn-engines` cache to the `geolibre-assets` cache.

- **`GEOLIBRE_NO_EXTERNAL_CDN=1`** – Disables all external CDN references, effectively removing the need for the CDN engine caching rule as all resources are served same-origin.

## Implementation Details in the Codebase

The caching behavior is configured and enforced across several key files:

- **[`apps/geolibre-desktop/vite.config.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/vite.config.ts)** – Contains the Workbox configuration where the `geolibre-cdn-engines` route is defined. This file specifies the CacheFirst strategy and the URL patterns to match.

- **[`docs/architecture.md`](https://github.com/opengeos/GeoLibre/blob/main/docs/architecture.md)** – Lines 95-102 provide the high-level design documentation for the offline support layer, detailing the three cache tiers and the CDN engine strategy.

- **[`apps/geolibre-desktop/src/lib/offline-tiles.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/lib/offline-tiles.ts)** – Demonstrates the fetch-through-service-worker pattern used to populate caches. While focused on map tiles, the same mechanism applies to CDN engine requests.

- **[`workers/tiles/src/index.ts`](https://github.com/opengeos/GeoLibre/blob/main/workers/tiles/src/index.ts)** – Implements low-level Cloudflare Workers cache logic (e.g., `cf: { cacheEverything: true, cacheTtl: ... }`) that underpins the runtime caching strategy for edge-deployed resources.

## Managing the Cache Programmatically

Developers can interact with the CDN engine cache directly through the Cache Storage API to force fresh downloads or inspect stored engines.

The following example demonstrates loading Pyodide and verifying cache behavior:

```typescript
// Example: loading the Pyodide engine (always CDN-served)
import { loadPyodide } from "jsdelivr-pyodide-loader";

// The first call triggers a network request that the service worker caches.
await loadPyodide();   // → fetches https://cdn.jsdelivr.net/.../pyodide.wasm

// Subsequent calls are served from the service worker cache (offline).
await loadPyodide();   // → served from CacheFirst route, no network traffic

```

To force a re-download after a version bump or for debugging purposes:

```typescript
// Example: forcing a re-download of a CDN engine
if (navigator.serviceWorker?.controller) {
  // Delete the cached entry for the engine URL
  const cache = await caches.open('geolibre-cdn-engines');
  await cache.delete('https://cdn.jsdelivr.net/npm/pyodide@0.26.1/pyodide.wasm');
}

// The next load will fetch the engine anew and repopulate the cache.
await loadPyodide();

```

## Summary

- GeoLibre implements a **three-tier caching system** via Workbox, with a dedicated `geolibre-cdn-engines` cache for heavy WebAssembly modules.
- The **CacheFirst** strategy ensures engines work offline after the first download while avoiding unnecessary network requests.
- **Version-bound URLs** (e.g., `pyodide@0.26.1`) prevent stale cache entries by creating unique cache keys for each release.
- **Environment flags** (`GEOLIBRE_PGLITE_CDN`, `GEOLIBRE_CEREUS_CDN`, `GEOLIBRE_NO_EXTERNAL_CDN`) allow developers to bundle engines locally, bypassing CDN caching entirely.
- Cache configuration resides in [`apps/geolibre-desktop/vite.config.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/vite.config.ts), with architectural documentation in [`docs/architecture.md`](https://github.com/opengeos/GeoLibre/blob/main/docs/architecture.md).

## Frequently Asked Questions

### How does GeoLibre handle CDN engine updates without serving stale cached versions?

Because the CDN URLs include exact version numbers (e.g., `https://cdn.jsdelivr.net/npm/pyodide@0.26.1/`), each version creates a unique cache key. When GeoLibre upgrades to a new engine version, the URL changes, causing the service worker to fetch and cache the new version while the old version remains available offline but unused. This eliminates cache invalidation issues common to version-agnostic URLs.

### Can I use GeoLibre completely offline without any CDN dependencies?

Yes. Setting the environment variable `GEOLIBRE_NO_EXTERNAL_CDN=1` during the build process bundles all engines locally under `/assets/`. This removes all external CDN references, allowing the standard asset precaching and runtime caching to handle engine storage without any network requirements after the initial installation.

### What happens if a CDN engine fails to fetch while the user is online?

The `CacheFirst` strategy only checks the cache **after** confirming a cache miss. If the network request fails (e.g., CDN outage) and no cached version exists, the fetch will fail and the application must handle the error. However, once successfully cached, subsequent requests are served from `geolibre-cdn-engines` regardless of network state.

### Where is the service worker caching strategy configured in the source code?

The primary configuration resides in [`apps/geolibre-desktop/vite.config.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/vite.config.ts), where the `vite-plugin-pwa` Workbox options define the `geolibre-cdn-engines` CacheFirst route. The architectural rationale and cache layer specifications are documented in [`docs/architecture.md`](https://github.com/opengeos/GeoLibre/blob/main/docs/architecture.md) (lines 95-102), while [`workers/tiles/src/index.ts`](https://github.com/opengeos/GeoLibre/blob/main/workers/tiles/src/index.ts) contains complementary Cloudflare Workers cache logic for edge-cached resources.