# Using Shapely for In-Browser Geospatial Analysis with Pyodide in GeoLibre

> Execute client-side geospatial analysis directly in your browser with Shapely and Pyodide in GeoLibre. Perform complex operations without server round trips.

- Repository: [Open Geospatial Solutions/GeoLibre](https://github.com/opengeos/GeoLibre)
- Tags: tutorial
- Published: 2026-07-31

---

**Yes, GeoLibre ships a built-in Pyodide environment that includes Shapely through the geopandas package, enabling complete client-side geospatial analysis without server round-trips.**

GeoLibre is an open-source geospatial platform that embeds a full Python runtime via Pyodide, allowing you to execute vector geometry operations directly in the browser. By bundling Shapely as a WebAssembly-compiled dependency of geopandas, GeoLibre eliminates the need for a Python backend while maintaining full API compatibility with standard desktop GIS workflows.

## How Pyodide Loads Shapely in GeoLibre

### Configuration and Package Distribution

The Pyodide integration is configured in [`apps/geolibre-desktop/src/lib/pyodide/pyodide-config.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/lib/pyodide/pyodide-config.ts), where lines 6-8 explicitly document that as of Pyodide 0.27.x, the **geopandas** distribution ships with **shapely**, pyproj, and PROJ data as pre-compiled wheels. This means a single call to `loadPackage("geopandas")` automatically retrieves the entire dependency graph, including the Shapely C extension compiled to WebAssembly.

### WebAssembly Loading Process

When your code invokes `geolibre.load_package("geopandas")`, the Pyodide Web Worker defined in [`apps/geolibre-desktop/public/pyodide/pyodide-worker.js`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/public/pyodide/pyodide-worker.js) (line 39) handles the download and initialization. The worker loads the geopandas wheel, which contains the Shapely libraries, into the browser's memory space where they execute as optimized WebAssembly code rather than JavaScript.

## Running Shapely Geometry Operations in the Browser

### Loading Dependencies

Before executing spatial analysis, initialize the environment by loading the geopandas package. This call downloads and caches Shapely and its dependencies the first time it runs:

```python
await geolibre.load_package("geopandas")

```

### Practical Code Examples

Once loaded, you can import Shapely classes and perform complex vector operations. The following example demonstrates geometry creation, spatial predicates, buffering, overlays, and GeoPandas integration:

```python
from shapely.geometry import Point, Polygon, LineString

# Geometry creation

pt = Point(12.4924, 41.8902)  # Rome Colosseum coordinates

poly = Polygon([(-0.1, 51.5), (0.1, 51.5), (0.1, 51.6), (-0.1, 51.6)])

# Spatial predicates

print(pt.within(poly))
print(poly.contains(pt))

# Buffering operations (creates circular polygon)

buffered = pt.buffer(0.01)  # ~1km buffer at this latitude

print(buffered.area)

# Overlay analysis (line intersection)

line = LineString([(-0.05, 51.55), (0.05, 51.55)])
intersection = poly.intersection(line)
print(intersection.wkt)

# Integration with GeoPandas

import geopandas as gpd
gdf = gpd.GeoDataFrame({"geometry": [pt, poly]}, crs="EPSG:4326")
print(gdf.total_bounds)

```

## Performance and Compatibility Considerations

### WebAssembly Execution Constraints

Shapely operations run as **WebAssembly** code within the browser's sandbox. While the compiled C extensions provide near-native speed, execution remains constrained by browser memory limits and single-threaded processing. Large vector datasets should be simplified or spatially filtered before processing to prevent memory exhaustion.

### API Version Alignment

GeoLibre standardizes on **Shapely ≥2.0**, as declared in [`backend/geolibre_server/pyproject.toml`](https://github.com/opengeos/GeoLibre/blob/main/backend/geolibre_server/pyproject.toml). This version alignment ensures that geometry operations available in the browser match those implemented in the optional backend server (see [`backend/geolibre_server/geolibre_server/vector_ops.py`](https://github.com/opengeos/GeoLibre/blob/main/backend/geolibre_server/geolibre_server/vector_ops.py) for reference implementations). All core APIs—including spatial predicates, buffering, overlays, and unary unions—function identically across both environments.

### Privacy and Architecture Benefits

Using Shapely via Pyodide requires **no Python sidecar** (`backend/geolibre_server`). All calculations occur client-side, ensuring sensitive geospatial data never leaves the user's browser while eliminating network latency for computational tasks.

## Key Source Files

The integration relies on the following components:

| Component | Path | Purpose |
|-----------|------|---------|
| Pyodide Configuration | [`apps/geolibre-desktop/src/lib/pyodide/pyodide-config.ts`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src/lib/pyodide/pyodide-config.ts) | Defines Pyodide version and documents Shapely inclusion in geopandas |
| Web Worker Loader | [`apps/geolibre-desktop/public/pyodide/pyodide-worker.js`](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/public/pyodide/pyodide-worker.js) | Executes package loading at line 39 |
| Backend Dependencies | [`backend/geolibre_server/pyproject.toml`](https://github.com/opengeos/GeoLibre/blob/main/backend/geolibre_server/pyproject.toml) | Pins `shapely>=2.0` for version consistency |
| Reference Implementation | [`backend/geolibre_server/geolibre_server/vector_ops.py`](https://github.com/opengeos/GeoLibre/blob/main/backend/geolibre_server/geolibre_server/vector_ops.py) | Demonstrates compatible Shapely usage patterns |

## Summary

- GeoLibre provides **Shapely ≥2.0** through its Pyodide distribution bundled with geopandas.
- Load the library using `await geolibre.load_package("geopandas")` in any browser-based Python context.
- All geometry operations execute client-side via **WebAssembly** without requiring the backend server.
- Browser memory limits constrain the size of datasets that can be processed efficiently.
- Configuration and loading logic reside in [`pyodide-config.ts`](https://github.com/opengeos/GeoLibre/blob/main/pyodide-config.ts) and [`pyodide-worker.js`](https://github.com/opengeos/GeoLibre/blob/main/pyodide-worker.js).

## Frequently Asked Questions

### Does using Shapely in GeoLibre require a Python backend?

No. All Shapely operations run client-side in the browser through Pyodide's WebAssembly runtime. You do not need to deploy the `backend/geolibre_server` sidecar, which ensures data remains local and private while eliminating server latency.

### Which Shapely version is available in the browser environment?

GeoLibre ships **Shapely 2.0 or higher** in its Pyodide build, matching the requirement specified in [`backend/geolibre_server/pyproject.toml`](https://github.com/opengeos/GeoLibre/blob/main/backend/geolibre_server/pyproject.toml). This version includes vectorized geometry operations and maintains full API compatibility with standard desktop installations.

### How do I import Shapely in a GeoLibre notebook?

Import Shapely after loading the geopandas package. Run `await geolibre.load_package("geopandas")` in the Python console or Jupyter-lite cell, then use standard import statements like `from shapely.geometry import Point, Polygon`.

### What are the limitations of running Shapely via Pyodide?

While core C-extension functions work via WebAssembly, you are constrained by **browser memory limits** and cannot use optional external native libraries not included in the Pyodide distribution. For large datasets, preprocess data or use spatial indexing to minimize memory consumption.