MapLibre-Geoman with Vite: draw and export GeoJSON

Published Nov 20, 2024
Updated
MapLibre-Geoman with Vite: draw and export GeoJSON
Niclas Priess
Niclas Priess
Head of Sales

This starter uses Vite, MapLibre GL JS and MapLibre-Geoman Free to draw and edit GeoJSON. It needs no account or basemap token. The map starts with a blank style so you can focus on the drawing tools; add your preferred basemap style for a production application.

Create the Vite application

npm create vite@latest maplibre-geoman-vite -- --template vanilla
cd maplibre-geoman-vite
npm install
npm install [email protected] @geoman-io/[email protected]

This guide uses JavaScript. For TypeScript projects, the package provides types; use the installation reference for your installed release's options and event types.

Initialize the map and Geoman

Create src/geoman-editor.js. This exact module is exercised in our browser example checks.

import * as ml from "maplibre-gl"
import workerUrl from "maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url"
import { Geoman } from "@geoman-io/maplibre-geoman-free"
import "maplibre-gl/dist/maplibre-gl.css"
import "@geoman-io/maplibre-geoman-free/dist/maplibre-geoman.css"

ml.setWorkerUrl(workerUrl)

export async function createEditor(
  container,
  initialData = { type: "FeatureCollection", features: [] },
) {
  const map = new ml.Map({
    container,
    center: [0, 0],
    zoom: 2,
    // A blank map works without a token. Substitute your own basemap style.
    style: { version: 8, sources: {}, layers: [] },
  })
  const geoman = new Geoman(map)
  await new Promise((resolve) => geoman.mapAdapter.once("gm:loaded", resolve))
  await geoman.features.importGeoJson(initialData)

  return { map, geoman, getData: () => geoman.features.exportGeoJson() }
}

The separate worker import matters for MapLibre GL JS 6 with Vite. gm:loaded signals that Geoman is ready for feature imports and draw-mode calls; it is different from the map's own load event. mapAdapter provides Geoman event typing when you move this code to TypeScript.

Add a container and export control

Replace src/main.js with:

import { createEditor } from "./geoman-editor.js"
import "./style.css"

const app = document.querySelector("#app")
app.innerHTML = `
  <h1>Draw and edit GeoJSON</h1>
  <div id="map"></div>
  <button id="export" disabled>Export GeoJSON</button>
  <pre id="output"></pre>
`

const editor = await createEditor("map")
const exportButton = document.querySelector("#export")
exportButton.disabled = false
exportButton.addEventListener("click", () => {
  document.querySelector("#output").textContent = JSON.stringify(
    editor.getData(),
    null,
    2,
  )
})

Replace src/style.css with:

body {
  margin: 0;
  font-family: system-ui, sans-serif;
}
#app {
  padding: 16px;
}
#map {
  height: 65vh;
  min-height: 320px;
}
button {
  margin-top: 12px;
  padding: 8px 16px;
}
pre {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

Run npm run dev, choose the polygon tool, draw an area and click Export GeoJSON. Call editor.map.remove() when removing this map from a longer-lived application. Framework components should do that in their unmount cleanup.

Import existing features

Pass a GeoJSON feature collection as the second argument to createEditor. The function imports it after Geoman finishes initializing. Keep Geoman's feature properties when exporting and re-importing data. See the Features API for supported shapes and metadata.

Common setup issues

  • Worker loading errors: keep the Vite worker URL import and setWorkerUrl call before constructing the map.
  • Unstyled controls: load both MapLibre and Geoman CSS.
  • Blank map area: set an explicit height. This example deliberately has no basemap tiles.
  • Tool calls do nothing: wait for gm:loaded before enabling a drawing mode.

Explore React, Vue, Next.js and other examples, try the full MapLibre demo, or compare Free and Pro.

Want more geo-editing insights?

Get tips, tutorials, and product updates delivered to your inbox.

No spam. Unsubscribe anytime.


Keywords

Get geo-editing tips & product updates

We'll email you updates. Unsubscribe anytime. Privacy Policy

© 2026 Geoman. All rights reserved.

Summarize with AI