@moritzbrantner/maps
v0.1.5
Published
React map components and temporal geo utilities backed by density-aware aggregation.
Readme
@moritzbrantner/maps
React map components, density aggregation helpers, GeoJSON editing, and temporal geo utilities for interactive spatial views.
Install
bun add @moritzbrantner/maps @moritzbrantner/ui react react-domnpm install @moritzbrantner/maps @moritzbrantner/ui react react-domImport the stylesheet once in your app shell:
import "@moritzbrantner/maps/styles.css";The default stylesheet includes package map styles and MapLibre GL CSS without Tailwind preflight. If you need the legacy global reset, import:
import "@moritzbrantner/maps/styles.full.css";Live demo: https://moritzbrantner.github.io/maps/
Which Map Should I Use?
| Need | Use |
| --- | --- |
| Plain point markers | PointMap |
| Proportional point markers | BubbleMap |
| Dense point aggregation and clusters | ClusteredMap |
| Point density or scalar field surfaces | HeatMap / HeatFieldMap |
| Origin-destination connections | FlowMap |
| Mixed GeoJSON display | GeoJsonMap |
| Moving point tracks | TemporalClusteredMap / TemporalHeatMap |
| Multiple coordinated layers | MapView with MapLayers |
| Create, reshape, group, or delete GeoJSON | EditableGeoJsonMap |
Minimal Example
import "@moritzbrantner/maps/styles.css";
import { ClusteredMap, type MapPoint } from "@moritzbrantner/maps";
const points: MapPoint[] = [
{ id: "berlin", latitude: 52.52, longitude: 13.405, metrics: { demand: 42 } },
];
export function FleetMap() {
return (
<ClusteredMap
defaultViewState={{ center: [13.405, 52.52], zoom: 8 }}
points={points}
style={{ height: 420 }}
/>
);
}Common Controls
Compose overlays with the built-in legend components and keep feature state controlled when the surrounding app owns side panels, tables, or detail views.
import {
ClusteredMap,
MapColorRampLegend,
type MapSurfaceController,
} from "@moritzbrantner/maps";
let controller: MapSurfaceController | null = null;
<ClusteredMap
onMapControllerReady={(next) => {
controller = next;
}}
onSelectedFeatureIdChange={(featureId) => setSelectedId(featureId)}
points={points}
selectedFeatureId={selectedId}
>
<MapColorRampLegend
stops={[[0, "#67e8f9"], [1, "#dc2626"]]}
title="Demand"
/>
</ClusteredMap>;
controller?.fitPoints(points, { padding: 72 });Documentation
- Getting Started
- Entrypoints
- API Stability
- Contributing
- Security
- Recipes
- GeoJSON
- GeoJSON Editor
- Timeline And Temporal Maps
- Performance
- SSR And Next.js
- GeoJSON Transition Future Goals
Runtime Notes
- Rendered React maps require the
react,react-dom, and@moritzbrantner/uipeer dependencies. @moritzbrantner/timeline-editoris an optional peer required only for timeline editor components.- MapLibre, Three, Turf helpers, supercluster, d3-delaunay, polygon-clipping, and related map/runtime packages are included as package dependencies.
- Rendering map components requires browser DOM APIs and WebGL/canvas support.
- React map entrypoints are client components and start with
"use client". @moritzbrantner/maps/styles.cssis compiled CSS that includes package styles and MapLibre GL CSS without Tailwind preflight/global reset.@moritzbrantner/maps/styles.full.cssis a compatibility stylesheet that includes Tailwind preflight/global reset.@moritzbrantner/maps/coreis intended for data-only usage and must remain free of React, DOM, MapLibre, Three,@moritzbrantner/ui, and timeline editor runtime imports.
Verification
The release contract is:
bun run verify:fast
bun run test:browser
bun run verify:benchmarks