Skip to content

Editor setup

maplibre-yaml publishes the format as JSON Schema. Any editor that runs the YAML language server reads it and gives you autocomplete, hover documentation and checks as you type, with nothing installed in your project. That covers VS Code (through the Red Hat YAML extension), Neovim, JetBrains IDEs and others.

  1. Install the YAML extension. In VS Code, install YAML by Red Hat from the Extensions view. In another editor, set up the yaml-language-server its documentation describes.

  2. Make this the first line of your map document. It is a comment, a modeline, naming the schema the file follows:

    # yaml-language-server: $schema=https://docs.maplibre-yaml.org/schema/latest/map.schema.json
    type: map
    id: my-map
    config:
    center: [-74.006, 40.7128]
    zoom: 12
    mapStyle: "https://tiles.openfreemap.org/styles/liberty"

Now press Ctrl+Space on an empty line for the keys that can go there, and hover a key for its description. Misspell a top-level key (layer: for layers:) and it is underlined. Files that mlym init creates already start with this line.

The modeline travels with the file, so anyone who opens it gets the same help, with no shared editor settings. A story file uses its own schema:

# yaml-language-server: $schema=https://docs.maplibre-yaml.org/schema/latest/map.schema.json
type: map
  • Autocomplete for every key, layer type, control and source type.
  • Hover documentation, the same descriptions the YAML reference shows.
  • Checks as you type for structure, allowed values and types. Unknown keys are flagged; x-* keys are always allowed, for extensions. MapLibre options inside config: and extra source options are allowed, as they are when the map renders.

The schema checks the shape of the file. The validator, mlym validate, checks more: a layer naming a source the document doesn’t declare (with a “did you mean”), a misspelt fitTo source, or a map with no basemap. To see its findings in the editor too, add the VS Code task below.

FileSchema URL
Map document (type: map)https://docs.maplibre-yaml.org/schema/latest/map.schema.json
Story file (type: scrollytelling)https://docs.maplibre-yaml.org/schema/latest/scrollytelling.schema.json
Any of the abovehttps://docs.maplibre-yaml.org/schema/latest/any.schema.json

latest/ follows the newest release. To pin a version, use the copy inside the npm package, served by a CDN. It exists for every release from 0.4 on and never changes:

https://cdn.jsdelivr.net/npm/@maplibre-yaml/core@0.10/schemas/map.schema.json

Change the version after core@ to the one your project uses. Two numbers (0.9) name a release line and give its newest release; three (0.9.0) name exactly one release. The docs site also serves the current release line at https://docs.maplibre-yaml.org/schema/v0.10/<block>.schema.json; older lines there redirect to the CDN copy.

To give whole folders a schema without a line in every file, map globs to schemas in your project’s .vscode/settings.json:

{
"yaml.schemas": {
"https://docs.maplibre-yaml.org/schema/latest/map.schema.json": [
"**/*.map.yaml",
"maps/**/*.yaml"
],
"https://docs.maplibre-yaml.org/schema/latest/scrollytelling.schema.json": [
"**/*.story.yaml"
]
}
}

A modeline wins over yaml.schemas when a file has both, so you can set a default for a folder and override it per file. The repository has a complete settings.json.

A document written in JSON or TOML uses the same schemas. Each format names its schema its own way.

VS Code checks JSON against a schema with no extension installed. Name the schema with a $schema key at the top of the document. maplibre-yaml accepts the key and removes it before validating, so it never warns:

map.json
{
"$schema": "https://docs.maplibre-yaml.org/schema/latest/map.schema.json",
"type": "map",
"id": "my-map",
"config": {
"center": [-74.006, 40.7128],
"zoom": 12,
"mapStyle": "https://tiles.openfreemap.org/styles/liberty"
}
}

To leave the files as they are, map them to schemas with json.schemas in .vscode/settings.json instead. fileMatch takes file name patterns:

{
"json.schemas": [
{
"fileMatch": ["maps/*.json", "*.map.json"],
"url": "https://docs.maplibre-yaml.org/schema/latest/map.schema.json"
},
{
"fileMatch": ["*.story.json"],
"url": "https://docs.maplibre-yaml.org/schema/latest/scrollytelling.schema.json"
}
]
}

Taplo is the TOML language server; in VS Code it comes with the Even Better TOML extension. It reads a #:schema directive on the first line of the file:

map.toml
#:schema https://docs.maplibre-yaml.org/schema/latest/map.schema.json
type = "map"
id = "my-map"
[config]
center = [-74.006, 40.7128]
zoom = 12
mapStyle = "https://tiles.openfreemap.org/styles/liberty"

Without the directive, associate files with a schema in .vscode/settings.json. Each key is a regular expression matched against the file’s path:

{
"evenBetterToml.schema.associations": {
"maps/.*\\.toml$": "https://docs.maplibre-yaml.org/schema/latest/map.schema.json",
".*\\.story\\.toml$": "https://docs.maplibre-yaml.org/schema/latest/scrollytelling.schema.json"
}
}

Other editors that run Taplo read the same associations from a .taplo.toml file. mlym convert writes the schema line in the target’s form, so a converted file keeps its editor help.

The schemas ship inside the @maplibre-yaml/core npm package. With core installed, point the modeline at the file, relative to the YAML file:

# yaml-language-server: $schema=./node_modules/@maplibre-yaml/core/schemas/map.schema.json
type: map

Or write a copy next to your files with the CLI, which reads it from the installed core package, so it matches what mlym validate checks:

Terminal window
npx maplibre-yaml@latest schema map --out map.schema.json
# yaml-language-server: $schema=./map.schema.json
type: map

The schema can’t run the validator’s own rules. A VS Code task runs mlym validate on the open file and lists its errors, warnings and notes in the Problems panel, next to the lines they belong to.

Create or update .vscode/tasks.json in your project:

{
"version": "2.0.0",
"tasks": [
{
"label": "maplibre-yaml: Validate Current File",
"type": "shell",
"command": "npx",
"args": ["maplibre-yaml", "validate", "${file}", "--format", "vscode"],
"problemMatcher": {
"owner": "maplibre-yaml",
"fileLocation": "absolute",
"pattern": {
"regexp": "^(.+):(\\d+):(\\d+): (error|warning|info): (.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
"presentation": {
"reveal": "silent",
"panel": "shared"
},
"group": "build"
}
]
}

With the CLI installed in the project (npm install --save-dev @maplibre-yaml/cli), npx uses that copy; otherwise it downloads the CLI on the first run.

  1. Open a .yaml file.
  2. Press Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows and Linux).
  3. Type “Run Task” and choose maplibre-yaml: Validate Current File. The first time, VS Code may ask whether to allow the task: choose Allow.

To run it from a key, open Keyboard Shortcuts, search for “Run Task” and bind a key to it.

Findings appear in the Problems panel (Cmd+Shift+M / Ctrl+Shift+M) with their file, line and column: click one to jump to it. Errors show as errors and warnings as warnings. Notes, which explain how a valid value is read, show as information.

--format vscode prints one line per finding, file:line:column: severity: [path] message, which the problem matcher reads. The severity is error, warning, or info for a note, and the path is absolute, which is why the task sets "fileLocation": "absolute":

/home/you/maps/map.yaml:15:11: error: [config.center] center needs square brackets: center: [-74.006, 40.7128]
/home/you/maps/quakes.yaml:13:13: warning: [layers.0.source] Layer "quakes" uses source "quake", which is not declared under sources:. Did you mean "quakes"?
/home/you/maps/nyc.yaml:6:3: info: [config.mapStyle] mapStyle: "data/nyc.pmtiles" names a .pmtiles file, so it is read as a Protomaps basemap …

The repository has a complete tasks.json with three tasks:

  • Validate Current File: the open file.
  • Validate All Configs: every YAML file under configs/, grouped by file in the Problems panel. Change the pattern to your own folder.
  • Watch and Validate: runs in the background with --watch and updates the Problems panel each time you save.
  • Check that the YAML extension is installed and enabled.
  • The modeline must be the file’s first line, spelt exactly as above.
  • A format v2 file gets no help from these schemas (above).

The YAML extension doesn’t know the !html tag. Tell it in .vscode/settings.json:

{ "yaml.customTags": ["!html scalar"] }

Or write the value without the tag, as str: { $html: "…" }: it means the same thing (JSON & TOML).

Errors don’t appear in the Problems panel

Section titled “Errors don’t appear in the Problems panel”
  1. Check that the task has a problemMatcher.
  2. Check that --format vscode is in its args.
  3. Check that fileLocation is "absolute": the CLI prints full paths.
  4. Check the Problems panel’s filter.
  5. Notes missing? The regexp must match info as well as error and warning.
  1. Check that .vscode/tasks.json is in the folder you opened in VS Code.
  2. Check that the JSON is valid, then reload the window.

See VS Code’s Tasks documentation and problem matchers for more.