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.
Quick start
Section titled “Quick start”-
Install the YAML extension. In VS Code, install YAML by Red Hat from the Extensions view. In another editor, set up the
yaml-language-serverits documentation describes. -
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.jsontype: mapid: my-mapconfig:center: [-74.006, 40.7128]zoom: 12mapStyle: "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.jsontype: map# yaml-language-server: $schema=https://docs.maplibre-yaml.org/schema/latest/scrollytelling.schema.jsontype: scrollytellingWhat you get
Section titled “What you get”- 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 insideconfig: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.
Schema URLs and versions
Section titled “Schema URLs and versions”| File | Schema 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 above | https://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.jsonChange 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.
Without a modeline: VS Code settings
Section titled “Without a modeline: VS Code settings”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.
JSON and TOML documents
Section titled “JSON and TOML documents”A document written in JSON or TOML uses the same schemas. Each format names its schema its own way.
JSON in VS Code
Section titled “JSON in VS Code”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:
{ "$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" } ]}TOML with Taplo or Even Better TOML
Section titled “TOML with Taplo or Even Better TOML”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:
#:schema https://docs.maplibre-yaml.org/schema/latest/map.schema.jsontype = "map"id = "my-map"
[config]center = [-74.006, 40.7128]zoom = 12mapStyle = "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.
Offline / air-gapped
Section titled “Offline / air-gapped”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.jsontype: mapOr 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:
npx maplibre-yaml@latest schema map --out map.schema.json# yaml-language-server: $schema=./map.schema.jsontype: mapValidate on save (VS Code task)
Section titled “Validate on save (VS Code task)”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.
Step 1: Add the task
Section titled “Step 1: Add the task”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.
Step 2: Run the task
Section titled “Step 2: Run the task”- Open a
.yamlfile. - Press Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows and Linux).
- 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.
Step 3: Read the Problems panel
Section titled “Step 3: Read the Problems panel”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.
Output format
Section titled “Output format”--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 …Complete tasks.json
Section titled “Complete tasks.json”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
--watchand updates the Problems panel each time you save.
Troubleshooting
Section titled “Troubleshooting”No autocomplete or hover
Section titled “No autocomplete or hover”- 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).
!html is flagged as an unresolved tag
Section titled “!html is flagged as an unresolved tag”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”- Check that the task has a
problemMatcher. - Check that
--format vscodeis in itsargs. - Check that
fileLocationis"absolute": the CLI prints full paths. - Check the Problems panel’s filter.
- Notes missing? The
regexpmust matchinfoas well aserrorandwarning.
Task not found
Section titled “Task not found”- Check that
.vscode/tasks.jsonis in the folder you opened in VS Code. - Check that the JSON is valid, then reload the window.
See VS Code’s Tasks documentation and problem matchers for more.