swiftmap v0.6.0

A million points, and it still moves.

swiftmap keeps Leaflet's ergonomics — a few add_* calls, no projection argument, no view to set — and replaces its vector drawing with WebGL pipelines. This is not a screenshot. Drag it.

starting up…
Load
—points drawn
—mount → first paint
—fps while dragging

Synthetic western-Mediterranean vessel traffic, coloured by speed. The tiers are the same field at three densities — 19.1 MB of float64 coordinates for the largest, fetched only when you ask for it. The frame counter reads while you drag, because an idle map runs at your display's refresh rate no matter what is on it.

# traffic: 1,000,000 AIS pings -- lane, ferry, coastal, fishing, anchorage.
m = Map()
m.select("World Gray Canvas", scope="Basemaps")   # a bare Map() ships two
m.add_circle_markers(traffic, name="Vessel traffic", layer_group="AIS",
                     radius=2, color_col="speed_kn",
                     colormap="turbo", vmin=0, vmax=21)
m.configure_legend(show=True, title="Speed over ground (kn)")
The same core, four ways

Applications, not features

One rendering core serves notebooks, Shiny, React and Streamlit, with map state syncing both ways wherever there is a Python side to sync with. These are runnable apps rather than embeds, because “what does a production app look like” is a different question from “what can it do”.

Shiny for Python

Four runnable apps, from a basic map to a live feed and a draw-an-AOI filter. Map state syncs both ways: pan the map and Python sees the viewport; filter in Python and the map follows.

examples/shiny/
open on GitHub →

React

The core wrapped as a component over the npm package. Leaflet, glify and Geoman stay peer dependencies, so your bundler owns them and nothing is loaded twice.

examples/react/
open on GitHub →

Streamlit

A bidirectional component, its frontend bundled inside the wheel like the widget and the export -- clicks, draws and the viewport come back to Python on every rerun.

examples/streamlit/
open on GitHub →

Notebooks

Fourteen notebooks that are the long-form version of the gallery above, and the smoke test that runs on every change. Anywhere anywidget runs: JupyterLab, Notebook, VS Code.

examples/*.ipynb
open on GitHub →
Why this exists

The gap the other libraries leave open

folium and ipyleaflet have the ergonomics but hit a ceiling in the tens of thousands of features and offer flat layer controls. deck.gl scales, but it is a different mental model with a thin Python layer. swiftmap keeps the Leaflet model and adds the scale.

folium / ipyleafletdeck.gl (pydeck) kepler.gldatashaderswiftmap
Points before it stops being usabletens of thousandsmillionsmillionshundreds of millions millions — drag the map above
Mental modelLeafletits own layer/view stacka configurable appa rasterising pipeline Leaflet
What reaches the browserJSON per featuretyped arraysJSON or Arrowa rendered image binary float64 buffers
Per-feature click and hoveryesyesyesno — pixels, not features yes, at a million
Layer controlflat listbuild it yourselfflat list in its own UIyou compose it hierarchy from your columns
Cost of a layer togglere-renderre-renderre-renderre-raster a ~100-byte patch, at any scale
Python ↔ map syncone wayone wayone wayone way bidirectional (viewport, clicks, draws, time)
Time playbackplugin, DOM-basedmanualbuilt inmanual built in, filtered on the GPU
Offline / air-gappedCDN at view timeCDN at view timeCDN at view timerenders server-side everything inside the wheel
Static shareone HTML fileone HTML fileone HTML filean image, or a Panel app one HTML file, sidebar and time included
3D — extrusions, terrainnoyesyesno not yet

Measured, not claimed: the hero on the home page draws 1,000,000 points in roughly 800 ms from mount to first paint and stays interactive while you drag it — the readout under it is live, not a graphic. The other columns describe design centres; nothing here times them. Run your own comparison — the code behind every map on this site is printed underneath it.

The same comparison as a page of its own →

Where it misses, honestly

A comparison table that wins every row is a pitch, not an analysis. These are the places another library is the better answer today. They are known, they are on the list, and this section shrinks as they land — it has already lost density, raster imagery, WMS, offline, marker clustering and line direction since it was first written.

3D

No extrusions, no terrain, no camera pitch. deck.gl owns this, and a Leaflet-shaped library will always be a step behind it here.

Vector tiles

read_mvt brings a vector-tile dataset in as an ordinary table — the bridge, not a renderer. There is still no vector-tile basemap, so a style-driven basemap has to come in another way.

Earth-observation catalogues

add_imagery warps a raster you already have. STAC, COG and Earth Engine integration is leafmap's territory, not this library's.

First paint at the top end

Millions of points drag smoothly once they are there. Getting them there still costs more than it should on the very largest maps.

Install it

pip install swiftmap
Pulls in
anywidget numpy xyzservices and nothing else — no compiled bits, no Node
Never installs
pandas, polars, geopandas, geostructures — every one is supported as a data source, and swiftmap reads whichever you already have. None is a dependency.