npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mantine-map

v0.4.0

Published

Interactive maps for Mantine, powered by MapLibre GL

Readme

mantine-map

Interactive maps for Mantine, powered by MapLibre GL JS. Markers with Mantine tooltips and popovers, custom Mantine-styled controls (zoom, compass, fullscreen, geolocate), and polygons, all built on Mantine's polymorphic factory and styles API.

Installation

yarn add mantine-map maplibre-gl
# or
npm install mantine-map maplibre-gl

Import the styles once in your app, after the Mantine core styles. mantine-map/styles.css already includes the required maplibre-gl styles, so you do not need to import them separately:

import "@mantine/core/styles.css";
import "mantine-map/styles.css";

mantine-map does not ship any map tiles. Pass a style URL from a tile provider (for example MapTiler or CARTO) via the mapStyle prop. When omitted, the MapLibre demo basemap is used, which is for demonstration only.

mantine-map is published as ES modules only, matching maplibre-gl v6. Bundlers such as Next.js, Vite and webpack 5 need no configuration, and require() works on Node 22.12+ through its built-in ESM support. MapLibre GL JS v6 also requires WebGL2, which is available in all current browsers.

Worker setup (required)

MapLibre GL JS v6 loads its renderer worker from a URL instead of through the bundler's module graph, so the URL has to be supplied once before the first map is created. Without it the map mounts but never draws any tiles, leaving an empty box. setWorkerUrl is re-exported for convenience:

// Vite. `?worker&url` is required, not plain `?url`: the worker imports a sibling chunk at runtime.
import { setWorkerUrl } from "mantine-map";
import workerUrl from "maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url";

setWorkerUrl(workerUrl);
// webpack 5, rspack, rsbuild
import { setWorkerUrl } from "mantine-map";

setWorkerUrl(new URL("maplibre-gl/dist/maplibre-gl-worker.mjs", import.meta.url).toString());

With Next.js, copy both maplibre-gl-worker.mjs and maplibre-gl-shared.mjs out of node_modules/maplibre-gl/dist into public/, then point setWorkerUrl at them there, prefixed with your basePath if the app is deployed under one. The two files must stay side by side, because the worker imports the shared chunk as a sibling and a plain new URL(...) emits only the entry file.

Turbopack can also bundle the worker properly through new Worker(new URL(...)), which resolves that sibling import and needs no copied files. Reaching it is awkward, though: maplibre accepts only a URL string, and Turbopack does not expose the URL of a worker entry the way Vite's ?worker&url does. This repository's documentation site takes that route in docs/maplibre-worker-url.ts, which spells out what it depends on. Prefer the public/ copy above unless you specifically want to avoid the copy step.

Usage

import { Tooltip } from "@mantine/core";
import {
  IconCurrentLocation,
  IconMaximize,
  IconMinimize,
  IconMinus,
  IconNavigation,
  IconPlus,
} from "@tabler/icons-react";
import { Map } from "mantine-map";

function Demo() {
  return (
    <Map
      mapStyle="https://your-tile-provider/style.json"
      initialViewState={{ longitude: 2.3522, latitude: 48.8566, zoom: 11 }}
      style={{ height: 460 }}
    >
      <Map.Controls position="top-right">
        {/* Controls ship no icons, pass your own as children */}
        <Map.ControlGroup>
          <Map.ZoomInControl>
            <IconPlus size={18} />
          </Map.ZoomInControl>
          <Map.ZoomOutControl>
            <IconMinus size={18} />
          </Map.ZoomOutControl>
        </Map.ControlGroup>
        <Map.CompassControl>
          <IconNavigation size={18} />
        </Map.CompassControl>
        <Map.FullscreenControl>
          {(isFullscreen) =>
            isFullscreen ? <IconMinimize size={18} /> : <IconMaximize size={18} />
          }
        </Map.FullscreenControl>
        <Map.GeolocateControl>
          <IconCurrentLocation size={18} />
        </Map.GeolocateControl>
      </Map.Controls>

      <Tooltip label="Paris">
        <Map.Marker longitude={2.3522} latitude={48.8566} />
      </Tooltip>

      <Map.Polygon
        id="zone"
        coordinates={[
          [2.32, 48.87],
          [2.38, 48.87],
          [2.38, 48.84],
          [2.32, 48.84],
        ]}
        fillColor="blue"
      />
    </Map>
  );
}

Every subcomponent is also exported as a flat component (MapMarker, MapControls, MapZoomInControl, MapPolygon, ...) in addition to the Map.* static members.

Components

  • Map — the root. Owns the MapLibre instance and shares it through context. Accepts mapStyle (URL, style object, or a theme-aware { light, dark } pair swapped with the Mantine color scheme), initialViewState, minZoom/maxZoom, interactive, and onMapClick/onMove/onMoveEnd/onMapLoad. onMapClick receives the { longitude, latitude } under the pointer, so it can be handed straight to a Map.Marker to add markers on click, and stays distinct from the root element's plain onClick.
  • Map.Marker — renders custom content (or a default themed pin) at a coordinate. Supports draggable and onDragEnd. Attach a tooltip or popover by wrapping the marker with Mantine's Tooltip or Popover declaratively.
  • Map.Controls + Map.ZoomInControl, Map.ZoomOutControl, Map.CompassControl, Map.FullscreenControl, Map.GeolocateControl — Mantine ActionIcon controls, positioned in any corner. The library ships no icons: pass the icon of your choice as children of each control. Wrap adjacent controls in Map.ControlGroup to join them into one segmented block.
  • Map.Polygon — highlights an area via a GeoJSON fill + outline. Colors accept Mantine color keys.

Local development

  • npm run storybook — start Storybook
  • npm run dev — start the documentation site
  • npm run docgen — regenerate props documentation
  • npm run build — build the package
  • npm test — run the full check (format, typecheck, lint, jest)

Publishing

  1. Login with your npm account (npm login).
  2. Run npm run release:patch, npm run release:minor or npm run release:major to publish a new version.

The documentation is deployed to GitHub Pages automatically on release, based on the repository field in package/package.json. To publish it manually, run npm run docs:deploy.