Documentation

Every vector source can be previewed instantly — even if you never authored a style.json for it. When you request GET /styles/{id}/style.json and no [[styles]] entry matches {id}, but a vector source with that id exists, tileserver-rs generates a complete MapLibre GL v8 style on the fly.

When it triggers

ConditionResult
A [[styles]] entry matches the idThe configured style is returned (auto-gen is never consulted)
No style matches, but a vector source (PMTiles / MBTiles / MLT) shares the idAn auto-generated style is returned (200)
No style matches and the source is raster (COG, DEM, PNG)404 Style not found
Nothing matches the id at all404 Style not found

What the generated style looks like

For each entry in the source's TileJSON vector_layers, three paint layers are emitted so that any geometry renders regardless of what the layer contains:

  • a fill layer filtered to ["==", "$type", "Polygon"]
  • a line layer filtered to ["==", "$type", "LineString"]
  • a circle layer filtered to ["==", "$type", "Point"]

The $type filter collapses Multi* geometries to their singular form, so the three filters together cover every feature.

Layers are grouped all fills → all lines → all circles across source-layers so polygons never paint over points. Each source-layer gets a deterministic color (a stable hue derived from a hash of the layer id), with fill-outline-color always set and zoom-interpolated line-width / circle-radius.

Empty or missing vector_layers still yields a valid style with a single background layer — the viewer renders a blank map rather than erroring.

Example

curl -s http://localhost:8080/styles/protomaps/style.json | jq '.version, (.layers | length)'
# 8
# 10   (background + 3 kinds × 3 source-layers)

The generated style points its source at the TileJSON endpoint (/data/{id}.json). Any ?key= query is forwarded to that URL and to the glyphs URL. MLT sources emit inline .pbf tiles because maplibre-gl-js cannot decode MLT directly.

Providing your own style

To fully control the appearance, add a [[styles]] entry — it always takes precedence over auto-generation:

[[styles]]
id = "protomaps"
path = "/data/styles/protomaps/style.json"
name = "Protomaps"