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

maplibre-gl-basemap-control

v0.3.0

Published

A MapLibre GL JS control for searching and switching public basemaps

Readme

MapLibre GL Basemap Control

A MapLibre GL JS control for searching and switching public basemaps. It keeps the standard compact MapLibre control button, opens a floating searchable panel, and can be used from vanilla TypeScript or React.

npm version License: MIT

Features

  • Search-first basemap picker inspired by QuickMapServices
  • Built-in catalog for common public basemaps, MapTiler styles, Amazon Location styles, and Mapbox styles
  • Custom basemap and provider definitions
  • MapLibre IControl implementation
  • React wrapper and state hook
  • Vite library build with ESM/CJS outputs and TypeScript declarations
  • Docker and GitHub Actions examples workflow

Installation

npm install maplibre-gl-basemap-control maplibre-gl

Vanilla TypeScript

import maplibregl from 'maplibre-gl';
import { BasemapControl } from 'maplibre-gl-basemap-control';
import 'maplibre-gl-basemap-control/style.css';

const map = new maplibregl.Map({
  container: 'map',
  style: {
    version: 8,
    sources: {},
    layers: [{ id: 'background', type: 'background' }],
  },
  center: [0, 0],
  zoom: 2,
});

map.on('load', () => {
  const basemaps = new BasemapControl({
    title: 'Basemaps',
    collapsed: true,
    defaultBasemapId: 'carto-positron',
  });

  map.addControl(basemaps, 'top-right');
});

React

import { useEffect, useRef, useState } from 'react';
import maplibregl, { Map } from 'maplibre-gl';
import { BasemapControlReact, useBasemapState } from 'maplibre-gl-basemap-control/react';
import 'maplibre-gl-basemap-control/style.css';

function App() {
  const mapContainer = useRef<HTMLDivElement>(null);
  const [map, setMap] = useState<Map | null>(null);
  const { state, setState } = useBasemapState({
    collapsed: false,
    activeBasemapId: 'carto-positron',
  });

  useEffect(() => {
    if (!mapContainer.current) return;

    const mapInstance = new maplibregl.Map({
      container: mapContainer.current,
      style: { version: 8, sources: {}, layers: [{ id: 'background', type: 'background' }] },
      center: [0, 0],
      zoom: 2,
    });

    mapInstance.on('load', () => setMap(mapInstance));
    return () => mapInstance.remove();
  }, []);

  return (
    <>
      <div ref={mapContainer} />
      {map && (
        <BasemapControlReact
          map={map}
          collapsed={state.collapsed}
          activeBasemapId={state.activeBasemapId}
          onStateChange={setState}
          onBasemapChange={(basemap) => console.log(basemap.name)}
        />
      )}
    </>
  );
}

Custom Basemaps

The built-in catalog can be extended or replaced.

import type { BasemapDefinition } from 'maplibre-gl-basemap-control';

const customBasemaps: BasemapDefinition[] = [
  {
    id: 'example-raster',
    name: 'Example Raster',
    provider: 'example',
    type: 'raster',
    category: 'Custom',
    attribution: '&copy; Example Provider',
    source: {
      type: 'raster',
      tiles: ['https://tiles.example.com/{z}/{x}/{y}.png'],
      tileSize: 256,
      maxzoom: 19,
    },
    tags: ['custom', 'street'],
  },
];

const control = new BasemapControl({
  basemaps: customBasemaps,
  providers: [{ id: 'example', name: 'Example Provider', category: 'Custom' }],
  includeDefaultBasemaps: true,
});

Set includeDefaultBasemaps: false to use only your supplied catalog.

Keyed Provider Styles

The built-in catalog includes MapTiler styles such as Streets, Base, Dataviz, Outdoor, Topo, Satellite Hybrid, Satellite Plain, Aquarelle, Backdrop, Landscape, Ocean, Toner, OpenStreetMap, and Winter. It also includes Amazon Location styles: Standard, Monochrome, Hybrid, and Satellite. Mapbox styles include Streets, Outdoors, Light, Dark, Satellite, Satellite Streets, Navigation Day, and Navigation Night.

MapTiler and Amazon Location styles require API keys. Mapbox styles require an access token. Users can enter keys and tokens in the collapsible provider settings section in the control panel, or you can provide them when creating the control.

const control = new BasemapControl({
  defaultBasemapId: 'maptiler-streets',
  mapTilerApiKey: 'YOUR_MAPTILER_API_KEY',
  amazonApiKey: 'YOUR_AMAZON_LOCATION_API_KEY',
  awsRegion: 'us-east-1',
  mapboxAccessToken: 'YOUR_MAPBOX_ACCESS_TOKEN',
});

The default MapTiler style URLs follow this form:

https://api.maptiler.com/maps/{mapId}/style.json?key={api-key}

Amazon Location style URLs follow this form:

https://maps.geo.{aws-region}.amazonaws.com/v2/styles/{mapStyle}/descriptor?key={api-key}

Mapbox style URLs follow this form:

https://api.mapbox.com/styles/v1/mapbox/{styleId}?access_token={api-key}

API

BasemapControl Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | collapsed | boolean | true | Whether the panel starts collapsed | | position | string | 'top-right' | Preferred control position | | title | string | 'Basemaps' | Panel title and button label | | panelWidth | number | 340 | Floating panel width in pixels | | className | string | '' | Extra class for the control button container | | mapTilerApiKey | string | undefined | Initial MapTiler API key for built-in MapTiler styles | | amazonApiKey | string | undefined | Initial Amazon Location API key for built-in Amazon styles | | awsRegion | string | 'us-east-1' | AWS region for built-in Amazon Location styles | | mapboxAccessToken | string | undefined | Initial Mapbox access token for built-in Mapbox styles | | basemaps | BasemapDefinition[] | [] | Custom basemaps to add or use | | providers | BasemapProvider[] | [] | Custom provider labels | | includeDefaultBasemaps | boolean | true | Include the built-in public catalog | | defaultBasemapId | string | undefined | Basemap to apply after the control is added |

Methods

  • setBasemap(id) - Apply a basemap and remove the previous plugin-managed basemap
  • setMapTilerApiKey(apiKey) - Set or update the MapTiler API key used by MapTiler styles
  • setAmazonCredentials(apiKey, awsRegion) - Set or update Amazon Location credentials
  • setMapboxAccessToken(accessToken) - Set or update the Mapbox access token
  • getActiveBasemap() - Return the current basemap definition
  • getBasemaps() - Return the catalog
  • setBasemaps(basemaps) - Replace the catalog
  • toggle(), expand(), collapse() - Control panel visibility
  • getState(), setState(state) - Read or update UI state
  • on(event, handler), off(event, handler) - Subscribe to events
  • getMap(), getContainer() - Access MapLibre/control internals

The panel includes a before_id input for raster basemap insertion. Leave it empty or set it to none to add the basemap above existing layers, or enter a MapLibre layer id to insert the basemap before that layer.

Events

  • basemapchange
  • error
  • collapse
  • expand
  • statechange

Attribution

Built-in basemaps include attribution strings in their MapLibre source definitions. Consumers are responsible for confirming that selected providers and usage volumes match their project requirements.

Development

npm install
npm run dev
npm test
npm run build
npm run build:examples

Docker

docker build -t maplibre-gl-basemap-control .
docker run -p 8080:80 maplibre-gl-basemap-control

Open http://localhost:8080/maplibre-gl-basemap-control/ to view the examples.