react-simple-maplibre
v0.1.0
Published
React MapLibre map component with free tile defaults and marker support
Maintainers
Readme
react-simple-maplibre
Thin React helpers around MapLibre GL JS and react-map-gl (MapLibre build). Out of the box, Map needs no API keys: the default basemap is OpenFreeMap’s Positron style (free tiles built on OpenStreetMap–style data). Swap in any other mapStyle URL or object when you want a different provider—those may require their own keys or terms.
You also get an optional pulse marker + popup, and two line helpers: MapRoute for paths and MapArc for great-circle segments.
If you already live in raw react-map-gl, this is mostly defaults and a bit of glue—not a second map runtime.
Install
react-simple-maplibre declares maplibre-gl and react-map-gl as peer dependencies. They are not shipped inside this package, so your app must depend on them (same major lines this package supports). A typical first-time install is one line:
npm install react-simple-maplibre maplibre-gl react-map-glIf the project already uses MapLibre / react-map-gl, add only react-simple-maplibre and keep your existing versions compatible with the peer range in this package’s package.json.
You also need react and react-dom (^18 or ^19) in the app; npm 7+ may install missing peers for you, but pinning them yourself avoids surprises.
The Map component imports MapLibre’s CSS for you. If you split chunks in a way that drops that side effect, add:
import "maplibre-gl/dist/maplibre-gl.css";Minimal map
Give the container a height (the map fills width and height of its parent).
import { Map } from "react-simple-maplibre";
export function City() {
return (
<div style={{ width: "100%", height: 360 }}>
<Map
coordinate={{ longitude: -74.006, latitude: 40.7128 }}
cooperativeGestures
accentTheming
accentColor="#2563eb"
/>
</div>
);
}coordinate—[lng, lat]or{ longitude, latitude }. Centers the map and shows the default marker unless you overridemarker.- Omit
coordinateand passinitialViewStateinstead for a map with no built-in marker (dashboards, custom children only). cooperativeGestures— forwards to MapLibre; use on pages where the map sits in scrollable content so wheel/trackpad doesn’t hijack the page.accentTheming/accentColor— optional tint on Positron-like vector layers; marker color falls back tomarker.color, thenaccentColor, then the CSS variable--ascent-color, then a built-in gold.accentThemingdefaults to on; turn it off on non-Positron styles where those layer ids don’t exist.coordinateZoom— zoom whencoordinateis set (default 14).
Other defaults worth knowing: cooperativeGestures defaults to false; attributionControl defaults to false—enable it (or add your own attribution) where license terms require it.
Override the basemap with any MapLibre mapStyle URL or style object you already use.
Next.js App Router: this library’s components use client-only APIs. Put maps in a file marked "use client" or import them from a client component.
Marker and popup
marker accepts color, scale, children (replaces the default pulse), drag options, and a React popup mounted through MapLibre’s native Marker#setPopup.
<Map
coordinate={[-73.9654, 40.7829]}
cooperativeGestures
marker={{
popup: (
<div className="text-sm">
<p className="font-medium">Central Park</p>
</div>
),
popupOptions: { maxWidth: "280px" },
}}
/>If you don’t set popupOptions.anchor, MapLibre picks an anchor so the popup tends to stay on screen. Set anchor: "bottom" (or another fixed value) when you want a fixed tip.
defaultPopupOpen: true opens the popup once the marker is ready. popupOptions also supports optional onOpen / onClose callbacks (not passed into the Popup constructor; handled by this library).
Children: routes, arcs, anything else
Map forwards ref to MapRef from react-map-gl/maplibre and accepts the usual children (Source, Layer, controls, or react-map-gl Marker).
Polyline along coordinates ([lng, lat][], at least two points):
import { Map, MapRoute } from "react-simple-maplibre";
const trail: [number, number][] = [
[-74.006, 40.7128],
[-73.98, 40.75],
];
<Map initialViewState={{ longitude: -73.99, latitude: 40.73, zoom: 12 }}>
<MapRoute coordinates={trail} color="#0ea5e9" width={4} />
</Map>Optional onHover / onClick, paint / hoverPaint for MapLibre line paint.
Great-circle arcs (each segment needs id, from, to as [lng, lat]):
import { Map, MapArc } from "react-simple-maplibre";
const arcs = [
{ id: "nyc-lon", from: [-74.006, 40.7128], to: [-0.1276, 51.5074] },
];
<Map initialViewState={{ longitude: -30, latitude: 35, zoom: 2 }}>
<MapArc
data={arcs}
paint={{ "line-color": "#6366f1", "line-width": 2 }}
hoverPaint={{ "line-width": 4 }}
/>
</Map>greatCircleCoordinates(from, to) is exported if you need the sampled ring yourself.
Maputnik / free tiles
Same idea as the default map: help a Maputnik export avoid Mapbox / MapTiler-style URLs that need API keys, by swapping matching sources to free OpenFreeMap-style endpoints when the URL pattern matches.
transformStyleForFreeTiles(styleJson) performs that rewrite on glyphs and sprites too, where applicable.
If you pass customStyle on Map, that transform runs automatically and the result becomes the active style. If you already transformed the JSON yourself, pass it as mapStyle instead (avoid piping an already-free style through customStyle twice unless you know it’s harmless).
Types
Main exports from react-simple-maplibre:
Map, MapRoute, MapArc, transformStyleForFreeTiles, greatCircleCoordinates, mergeArcLinePaint
Types: SimpleMapProps, Coordinate, MapMarkerOptions, MapMarkerPopupOptions, MapRouteProps, MapArcProps, MapArcDatum, etc.
License
MIT
