Skip to content

Installation & versions

How you load maplibre-yaml depends on what you are building:

You’re makingLoad itStart with
A plain HTML page, on any static hostFrom a CDN: nothing to installBrowser usage (CDN)
An Astro site@maplibre-yaml/astro from npmQuick start: Astro site on GitHub Pages
A Vite project, or a React, Vue or Svelte app@maplibre-yaml/core from npmUsing a bundler (Vite)

New to all of this? Use the CDN: the quick start walks through it.

A plain HTML page needs three things in its <head>: MapLibre’s stylesheet, an import map that tells the browser where maplibre-gl is, and the script that defines <ml-map>. maplibre-yaml uses the page’s copy of MapLibre rather than bundling its own, so without the import map the page stays blank with Failed to resolve module specifier “maplibre-gl” in the console.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<!-- Without this line, phones lay the page out at desktop width and the map looks tiny -->
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>My map</title>
<link
href="https://unpkg.com/maplibre-gl@6/dist/maplibre-gl.css"
rel="stylesheet"
/>
<style>
/* <ml-map> has no size of its own: without a height the map is invisible */
ml-map {
display: block;
height: 400px;
}
</style>
<!-- Tell the browser where to find maplibre-gl -->
<script type="importmap">
{ "imports": { "maplibre-gl": "https://unpkg.com/maplibre-gl@6/dist/maplibre-gl.mjs" } }
</script>
<!-- Register the <ml-map> element -->
<script
type="module"
src="https://unpkg.com/@maplibre-yaml/core@0.10/register.js"
></script>
</head>
<body>
<ml-map src="./map.yaml"></ml-map>
</body>
</html>

Save this next to it as map.yaml, the file src="./map.yaml" loads:

map.yaml
type: map
id: earthquake-map
config:
center: [-120, 37]
zoom: 4
mapStyle: "https://tiles.openfreemap.org/styles/liberty"
layers:
- id: earthquakes
type: circle
source:
type: geojson
url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson"
paint:
circle-radius: 6
circle-color: "#e74c3c"

Serve the folder with npx serve . and open the address it prints. Opening the HTML file directly (a file:// address) doesn’t work: the browser blocks the page from fetching map.yaml. Another static server works too, but large data files (PMTiles, FlatGeobuf, GeoParquet, COG) need one that answers range requests, which npx serve does and python -m http.server doesn’t.

The version in @maplibre-yaml/core@0.10 names a release line: the address loads the newest release in that line, so bug fixes arrive by themselves, while the next line, which may change behaviour, never arrives by surprise. Change the number on purpose when you upgrade (Upgrading); these docs always show the current line. maplibre-gl@6 works the same way for MapLibre.

With npm and a bundler, install the package and maplibre-gl, then make your entry file do three things: point maplibre-gl 6 at its worker, register <ml-map>, and load MapLibre’s stylesheet. Starting from a new Vite project:

Terminal window
npm create vite@latest my-map -- --template vanilla
cd my-map
npm install @maplibre-yaml/core maplibre-gl@^6

Replace the contents of src/main.js with:

src/main.js
// maplibre-gl 6 loads its worker from a separate file. Inside a Vite bundle it
// cannot find that file by itself, so tell it where it is.
import { setWorkerUrl } from "maplibre-gl";
import workerUrl from "maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url";
import "@maplibre-yaml/core/register";
import "maplibre-gl/dist/maplibre-gl.css";
setWorkerUrl(workerUrl);

Without the worker lines, every map on maplibre-gl 6 fails with Worker failed to load. On maplibre-gl 4 or 5, leave them out: there is no worker file to import, and the build fails if you keep them.

Replace the <body> of index.html with:

<body style="margin: 0;">
<ml-map src="./map.yaml" style="display: block; height: 100vh;"></ml-map>
<script type="module" src="/src/main.js"></script>
</body>

Put map.yaml in the public/ folder (public/map.yaml), with any data files it loads. Vite serves public/ at the site root during npm run dev and copies it into dist/ on npm run build. A map.yaml next to index.html works in npm run dev but isn’t copied by npm run build, and the built site then shows YAML syntax error … <!doctype html>: the server answered with the page instead of the file.

npm run dev shows the map; npm run build and then npm run preview serve the production build.

The same entry file works with other bundlers and in React, Vue or Svelte apps: see React & other frameworks. The @maplibre-yaml/astro components do all of this for you.

maplibre-yaml is tested with maplibre-gl 4, 5 and 6; use 6 for a new project. (The package’s peer range, ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.4.1, also accepts 3, which isn’t tested.) @maplibre-yaml/astro needs 4 or later, and Cloud Optimized GeoTIFF (COG) sources need 4.5 or later. Keep MapLibre’s stylesheet on the same major version as its script.

maplibre-gl 6 is published only as an ES module: the browser file is dist/maplibre-gl.mjs, which is what the import map points at. It loads its worker from next to itself, which works from a CDN or any static server; only a bundle needs the worker step in Using a bundler.

To serve maplibre-yaml from your own site instead of a CDN, copy the package’s whole dist/ folder, not only register.browser.js: see Hosting maplibre-yaml’s own files.

A project keeps the version it was set up with. To move to a newer release, see Upgrading to 0.10.

To use the JavaScript API (YAMLParser, MapRenderer) on a plain page instead of the <ml-map> element, import the package from esm.sh. Keep the same import map, and add ?external=maplibre-gl so the library uses the maplibre-gl you pinned, not a second copy chosen by esm.sh:

<script type="importmap">
{ "imports": { "maplibre-gl": "https://unpkg.com/maplibre-gl@6/dist/maplibre-gl.mjs" } }
</script>
<script type="module">
import {
YAMLParser,
MapRenderer,
} from "https://esm.sh/@maplibre-yaml/core@0.10?external=maplibre-gl";
// Your map code here
</script>

The JavaScript API page continues from here. The package ships its own TypeScript types, so there is no @types package to install; they are listed in the TypeScript API.

<ml-map> can also take the document as JSON in its config attribute or property, or as YAML in a <script type="text/yaml"> child, for a page that builds the map in code. See HTML pages: the <ml-map> element.

Follow the quick start to build your first map (or the Astro quick start for an Astro site), then read Your first map, explained. Something not working? See Troubleshooting.