Quick Start

Get a map running in under a minute.

1. Install

npm install json-maps maplibre-gl

2. Import the Renderer

import { MapRenderer } from "json-maps";
import "maplibre-gl/dist/maplibre-gl.css";

3. Define a Spec

const spec = {
  basemap: "dark",
  center: [-73.98, 40.75],
  zoom: 13,
  markers: {
    "empire-state": {
      coordinates: [-73.9857, 40.7484],
      color: "#e74c3c",
      label: "Empire State Building",
      popup: "Iconic 102-story Art Deco skyscraper",
    },
  },
};

4. Render It

<MapRenderer spec={spec} />

That's it. The MapRenderer component takes a MapSpec object and renders a full interactive MapLibre map.

Try the Playground

The fastest way to experiment is the Playground. Type JSON on the left, see the map update on the right.

Try pasting this:

{
  "basemap": "streets",
  "center": [-122.4194, 37.7749],
  "zoom": 13,
  "pitch": 60,
  "bearing": -30,
  "markers": {
    "golden-gate": {
      "coordinates": [-122.4786, 37.8199],
      "color": "#e74c3c",
      "label": "Golden Gate Bridge"
    },
    "fishermans-wharf": {
      "coordinates": [-122.4177, 37.8080],
      "color": "#3498db",
      "label": "Fisherman's Wharf"
    }
  }
}

This shows San Francisco with a 3D perspective, street basemap, and two markers.

Reactive Updates

The renderer reacts to spec changes. When you update the spec object, the map smoothly transitions:

  • Basemap changes swap the style
  • Viewport changes animate with flyTo()
  • Bounds changes use fitBounds() with padding
  • Markers are diffed by key — added, updated, or removed individually
// Change the spec and the map animates
const [spec, setSpec] = useState({ basemap: "light", zoom: 2 });

// Later...
setSpec({ basemap: "dark", center: [139.69, 35.68], zoom: 14 });
// Map flies to Tokyo with dark basemap