Skip to content

Installation

maplibre-yaml works with maplibre-gl v4, v5 and v6 (v6 recommended for new projects); the peer range is ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.4.1. Every example below pins major 6 (maplibre-gl@^6 for npm, maplibre-gl@6 for the CSS and the import map). Pin whichever supported major your project uses, and keep the CSS on the same major as the JS.

maplibre-gl v6 is ESM-only: the browser entry is dist/maplibre-gl.mjs (there is no maplibre-gl.js UMD file any more), so an import map points at that file directly. It loads its worker (maplibre-gl-worker.mjs) from next to its own module, which works as-is from a CDN or any static server.

Bundlers (Vite, webpack, …) on v6: inside a bundle MapLibre cannot find its worker, and every map fails with “Worker failed to load” (maplibre-yaml’s ml-map:error then spells out this fix). Tell MapLibre where the worker is before the first map renders — with Vite:

import { setWorkerUrl } from "maplibre-gl";
import workerUrl from "maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url";
setWorkerUrl(workerUrl);

The @maplibre-yaml/astro components do this for you. v4 and v5 need nothing.

Terminal window
npm install @maplibre-yaml/core maplibre-gl@^6

MapLibre GL JS requires its CSS for proper rendering. Add it to your HTML or import it in your JavaScript:

<link
href="https://unpkg.com/maplibre-gl@6/dist/maplibre-gl.css"
rel="stylesheet"
/>

For quick prototypes or simple pages, you can use maplibre-yaml directly from a CDN — no build tools needed. An import map tells the browser where to find maplibre-gl, which is kept external (not bundled):

<!DOCTYPE html>
<html>
<head>
<link
href="https://unpkg.com/maplibre-gl@6/dist/maplibre-gl.css"
rel="stylesheet"
/>
<style>
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> web component -->
<script
type="module"
src="https://unpkg.com/@maplibre-yaml/core/register.js"
></script>
</head>
<body>
<ml-map src="/map.yaml"></ml-map>
</body>
</html>

To use the JavaScript API (YAMLParser, MapRenderer) from a CDN instead of the web component, import the package from esm.sh, which resolves yaml and zod for you. 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?external=maplibre-gl";
// Your map code here
</script>

To use the <ml-map> web component, import the registration module:

import "@maplibre-yaml/core/register";

Then use it in your HTML:

<ml-map
style="width: 100%; height: 400px;"
config='{"type":"map","id":"my-map","config":{"center":[-74,40],"zoom":10,"mapStyle":"https://demotiles.maplibre.org/style.json"},"layers":[]}'
>
</ml-map>

maplibre-yaml is written in TypeScript and includes type definitions. No additional @types packages are needed.

import { YAMLParser, MapRenderer } from "@maplibre-yaml/core";
import type { MapBlock } from "@maplibre-yaml/core";
// For a single `type: map` document:
const mapBlock: MapBlock = YAMLParser.parseMapBlock(yamlString);

Create a simple test to verify everything is working:

import { YAMLParser } from "@maplibre-yaml/core";
const yaml = `
type: map
id: test
config:
center: [0, 0]
zoom: 2
mapStyle: "https://demotiles.maplibre.org/style.json"
layers: []
`;
const result = YAMLParser.safeParseMapBlock(yaml);
if (result.success) {
console.log("✓ maplibre-yaml is working!");
console.log(" Map ID:", result.data.id);
} else {
for (const error of result.errors) {
console.error(`✗ ${error.path}: ${error.message}`);
}
}

Now that you have maplibre-yaml installed, let’s create your first map.