Skip to content

Painting

Ops that consume Features and put pixels on a canvas — flat fills, scatter dabs, brush strokes, stamps, text.

12 ops: brush-file, circles, fill-dabs, fill-solid, label-placement, line, line-stamp, stamp, stroke, text, text-draw, text-labels.

Ops with no demo image below produce no visible result on their own — they feed other nodes rather than paint.

Brush source. src is an @asset ref or a literal path/name resolved by the host’s AssetLoader.

Field Type Required Description
src string yes Asset reference (@name) or literal path.

Filled disks at every feature point (tiny-skia), with per-feature radius, color, opacity, and optional stroke ring. The crisp vector counterpart to MapLibre’s circle layer. Each paint property has an optional *-expr MapLibre-expression sibling evaluated per feature group.

A tile rendered with circles
A filled circle at every input point, with a stroke. style
Field Type Required Description
color color | $param | @node no sRGB hex color, $param reference, or @node scalar port.
color-expr no A MapLibre color expression (JSON array, e.g. [“match”, [“get”, “c”], “a”, “#f00”, “#0f0”]), evaluated per feature group; overrides the constant color.
features @node yes Reference to another node (@name).
opacity number (0…1) | $param | @node no
opacity-expr no A MapLibre number expression giving opacity, evaluated per feature group; multiplies both fill and stroke alpha. Overrides the constant opacity.
radius number (0…∞) | $param | @node no
radius-expr no A MapLibre number expression (px), evaluated per feature group; overrides the constant radius.
stroke-color color | $param | @node no sRGB hex color, $param reference, or @node scalar port.
stroke-color-expr no A MapLibre color expression for the stroke ring, evaluated per feature group; overrides the constant stroke-color.
stroke-width number (0…∞) | $param | @node no
stroke-width-expr no A MapLibre number expression (px) for the stroke ring, evaluated per feature group; overrides the constant stroke-width. A ring is drawn only when width > 0.

Watercolor scatter-dab fill with world-deterministic jitter (seamless across tiles).

A tile rendered with fill-dabs
The same polygons as scatter dabs — many soft, faint stamps instead of coverage. style
Field Type Required Description
color color | $param | @node yes sRGB hex color, $param reference, or @node scalar port.
features @node yes Reference to another node (@name).
hardness number (0…1) | $param | @node no
opacity number (0…1) | $param | @node yes
opacity-jitter number (0…1) | $param | @node no
paint number (0…1) | $param | @node no
position-jitter number (0…1) | $param | @node no
radius-px number (0…∞) | $param | @node yes
size-jitter number (0…1) | $param | @node no
spacing-px number (0…∞) | $param | @node yes
value-jitter number (0…1) | $param | @node no

Solid polygon fill with optional outline and Gaussian blur.

A tile rendered with fill-solid
Flat polygon fill, with an outline. style
Field Type Required Description
blur-sigma number (0…∞) | $param | @node no
blur-sigma-max number (0…∞) no Upper bound on blur-sigma for padding, required when blur-sigma is an @node port. Values above it are clamped.
edge color | $param | @node no sRGB hex color, $param reference, or @node scalar port.
edge-width number (0…∞) | $param | @node no
features @node yes Reference to another node (@name).
fill color | $param | @node yes sRGB hex color, $param reference, or @node scalar port.
fill-alpha number (0…1) | $param | @node no
fill-expr no A MapLibre color expression (JSON array, e.g. [“match”, [“get”, “class”], “water”, “#88c”, “#ccc”] or [“interpolate”, [“linear”], [“get”, “area”], 0, “#eef”, 1000, “#049”]), evaluated per feature group at paint time. When present it overrides the constant fill; a group whose expression doesn’t resolve to a color is not painted. Unlocks continuous data-driven fills that constant fill can’t express.
opacity-expr no A MapLibre number expression (JSON array) giving fill opacity, evaluated per feature group at paint time. When present it overrides the constant fill-alpha; a group whose expression doesn’t resolve to a number falls back to fill-alpha.

Place the labels of every text-labels layer against one shared collision index, the way maplibre-gl-js does — so a POI label can knock out an overlapping road name. labels lists the layers bottom-first (paint order, as in stack); priority is top-down, so the last entry places first and wins. Feed the result to each layer’s text-draw node.

Field Type Required Description
labels array of @node yes text-labels layers, bottom first. The topmost layer places first.

Brush stroke along MVT polylines.

Field Type Required Description
brush @node yes Reference to another node (@name).
color color | $param | @node yes sRGB hex color, $param reference, or @node scalar port.
dtime number (0…∞) | $param | @node no
dtime-stroke-curve array of array of number | string no Piecewise-linear [[t, y], ...] multiplier on dtime. y scales the per-vertex dtime — y=3 makes the brush linger 3× longer (slower hand), y=0.3 sweeps through 3× faster. Used with dynamics-driven brushes that respond to stroke speed.
features @node yes Reference to another node (@name).
hardness-stroke-curve array of array of number | string no Piecewise-linear [[t, y], ...] driving a libmypaint stroke input on the brush. t is normalized stroke progress in [0, 1]; y is an offset added to the setting’s base value. radius is log-space (y=-2.3 ≈ ×0.1, y=+0.69 ≈ ×2); opaque and hardness are linear.
opacity number (0…1) | $param | @node no
opacity-stroke-curve array of array of number | string no Piecewise-linear [[t, y], ...] driving a libmypaint stroke input on the brush. t is normalized stroke progress in [0, 1]; y is an offset added to the setting’s base value. radius is log-space (y=-2.3 ≈ ×0.1, y=+0.69 ≈ ×2); opaque and hardness are linear.
pressure-base number (0…1) | $param | @node no
pressure-jitter number (0…1) | $param | @node no
radius-px number (0…∞) | $param | @node no
radius-stroke-curve array of array of number | string no Piecewise-linear [[t, y], ...] driving a libmypaint stroke input on the brush. t is normalized stroke progress in [0, 1]; y is an offset added to the setting’s base value. radius is log-space (y=-2.3 ≈ ×0.1, y=+0.69 ≈ ×2); opaque and hardness are linear.

Repeat a sprite along each polyline, rotated to the line’s tangent (MapLibre line-pattern). Points/polygons ignored. width-px scales the image height to the stroke width; spacing-px sets the advance (0 = the scaled image width, seamless).

Field Type Required Description
features @node yes Reference to another node (@name).
image @node yes Reference to another node (@name).
opacity number (0…1) | $param | @node no
scale number (0…∞) | $param | @node no Extra uniform scale on top of the width fit. Default 1.0.
spacing-px number (0…∞) | $param | @node no Advance between stamps. 0 = the scaled image width (seamless tiling).
width-px number (0…∞) | $param | @node no Stroke width; the image height is fit to it. 0 = native height.

Stamp a sprite at every input point. Lines and polygons are ignored. Rotation, scale and position jitter are world-deterministic — a given point gets the same jitter no matter which tile renders it, and the three do not correlate. Provide either an image input (one sprite for every point) or, for a data-driven icon-image, a sprite atlas ref plus a name-expr that names each feature’s icon.

Field Type Required Description
features @node yes Reference to another node (@name).
image @node no Reference to another node (@name).
name-expr no A MapLibre expression giving each feature’s icon name (MapLibre data-driven icon-image), cropped per group from the sprite atlas. Used instead of an image input; any icon the bound sheet contains is croppable, so no enumeration is needed.
opacity number (0…1) | $param | @node no
opacity-expr no A MapLibre number expression giving opacity, evaluated per feature group; overrides the constant opacity.
position-jitter-px number (0…∞) | $param | @node no Per-point random offset, ±value canvas pixels, drawn independently on x and y. Breaks up the regular lattice a point-grid leaves. Default 0 (no offset).
rotation-deg number | $param | @node no Constant rotation around each point, in degrees clockwise.
rotation-deg-expr no A MapLibre number expression (degrees clockwise), evaluated per feature group; overrides the constant rotation-deg.
rotation-jitter-deg number (0…∞) | $param | @node no Per-point random rotation, ±value degrees.
scale number (0…∞) | $param | @node no Uniform scale applied to the sprite. Default 1.0 (native size).
scale-expr no A MapLibre number expression, evaluated per feature group; overrides the constant scale. A group whose expression doesn’t resolve to a number falls back to scale.
scale-jitter number (0…∞) | $param | @node no Per-point random scale, ±value as a fraction of scale (0.2 = ±20%).
sprite string no Asset reference (@name) or literal path.

Crisp constant-width vector stroke along feature polylines (tiny-skia), with cap/join and optional pixel dasharray. The sharp counterpart to line (painterly brush) — for clean cartographic road/boundary lines.

A tile rendered with stroke
Crisp constant-width stroke, with a dash pattern. style
Field Type Required Description
cap butt | round | square no
color color | $param | @node yes sRGB hex color, $param reference, or @node scalar port.
color-expr no A MapLibre color expression (JSON array, e.g. [“match”, [“get”, “class”], “river”, “#48b”, “#888”]), evaluated per feature group at paint time. When present it overrides the constant color; a group whose expression doesn’t resolve to a color falls back to color. Unlocks data-driven stroke colors.
dasharray array of number (0…∞) | string no On/off lengths in pixels; omit for solid. Each length may be a $param.
features @node yes Reference to another node (@name).
gap-width-expr no A MapLibre number expression (JSON array) giving the casing gap in pixels, evaluated per feature group at paint time. When present it overrides the constant gap-width-px; a group whose expression doesn’t resolve to a number falls back to gap-width-px.
gap-width-px number no MapLibre line-gap-width: when > 0 the stroke becomes a casing — two parallel bands of width-px each, their inner edges this many pixels apart (outer footprint gap + 2 * width, centred on the line). 0 strokes the centreline.
join miter | round | bevel no
opacity number (0…1) | $param | @node no
opacity-expr no A MapLibre number expression (JSON array) giving stroke opacity, evaluated per feature group at paint time. When present it overrides the constant opacity; a group whose expression doesn’t resolve to a number falls back to opacity.
width-expr no A MapLibre number expression (JSON array, e.g. [“interpolate”, [“linear”], [“zoom”], 10, 1, 16, 4]) giving stroke width in pixels, evaluated per feature group at paint time. When present it overrides the constant width-px; a group whose expression doesn’t resolve to a number falls back to width-px.
width-px number (0…∞) | $param | @node no

Text labels (MapLibre symbol-placement): placement: point (default) labels each feature point, line / line-center walk each polyline with tangent-rotated glyphs. font is an ordered fallback stack of font and/or glyphs source names; text is a literal string or a MapLibre string expression evaluated per feature group. Paint properties have optional *-expr siblings; layout knobs are build-time constants in em. Collision is on by default and is deterministic across tiles: candidates come from this tile plus the 8 neighbour tiles (host-bound under <source>.<layer>@dx,dy), so borders stay seamless. Set source/layer (the upstream feature source) to enable neighbour gathering; without them collision is centre-tile-only. icon-name / icon-name-expr add MapLibre’s icon-image half: the icon is placed together with the text against the same index, so a symbol shows both or neither unless icon-optional / text-optional say otherwise. font and text are required unless the symbol is icon-only.

Field Type Required Description
allow-overlap boolean no MapLibre text-allow-overlap: place the label even if it collides. It still reserves its box (blocking later labels) unless ignore-placement. Default false.
anchor center | left | right | top | bottom | top-left | top-right | bottom-left | bottom-right no Which part of the label block sits on the point (point placement). Default center.
anchor-variants array of center | left | right | top | bottom | top-left | top-right | bottom-left | bottom-right no MapLibre text-variable-anchor: anchors tried in order on collision, the first free one placed (point placement). Overrides anchor when set.
collide boolean no Whether to run deterministic label collision. Default true (MapLibre’s default). Set false to draw every label (the pre-collision behaviour).
color color | $param | @node no sRGB hex color, $param reference, or @node scalar port.
color-expr no A MapLibre color expression, evaluated per feature group; overrides the constant color.
features @node yes Reference to another node (@name).
filter-expr no The upstream features filter, reproduced when gathering neighbour candidates so they are filtered identically to this tile’s own features. Set it to whatever the features node uses.
font array of string no Ordered fallback stack of font and/or glyphs source names from the document’s sources. Outline fonts and SDF glyph stacks mix freely; the first entry covering a char shapes it. Also the default/fallback stack for font-expr and unlisted font-stacks keys.
font-expr no A MapLibre expression yielding an array of font names, evaluated per feature group (MapLibre data-driven text-font); overrides the constant font. Each result is canonicalized (names joined with ,) and looked up in font-stacks; an unlisted stack, a non-array result, or an eval error falls back to font. Every stack a host may need must be enumerable in font-stacks (wasm hosts pre-bind glyph assets).
font-stacks object no Named dynamic font stacks: canonical stack key (font names joined with ,) → ordered font/glyphs source names. Consulted by font-expr and by format text sections carrying text-font. Declaration order fixes each stack’s stable id (used by the layout cache and cross-tile collision).
halo-color color | $param | @node no sRGB hex color, $param reference, or @node scalar port.
halo-color-expr no A MapLibre color expression for the halo, evaluated per feature group; overrides the constant halo-color.
halo-width number (0…∞) | $param | @node no Halo radius in px around each glyph. Default 0 (no halo).
halo-width-expr no A MapLibre number expression (px), evaluated per feature group; overrides the constant halo-width.
icon-allow-overlap boolean no MapLibre icon-allow-overlap. A symbol carries one overlap decision, so with text present this and allow-overlap must both be set for the symbol to ignore collision. Default false.
icon-anchor center | left | right | top | bottom | top-left | top-right | bottom-left | bottom-right no Which part of the icon sits on the point (MapLibre icon-anchor). Default center.
icon-ignore-placement boolean no MapLibre icon-ignore-placement; with text present it pairs with ignore-placement the same way as the overlap flags. Default false.
icon-name string no Constant MapLibre icon-image: the sprite to draw at each point, cropped from icon-sprite. Needs icon-sprite.
icon-name-expr no A MapLibre expression naming each feature’s icon (data-driven icon-image), cropped from icon-sprite; overrides icon-name. A group resolving to an empty/unknown name draws no icon and places as a text-only symbol.
icon-offset array of number no MapLibre icon-offset: shift [x, y] in px, itself scaled by icon-size. Default [0, 0].
icon-opacity number (0…1) | $param | @node no
icon-opacity-expr no A MapLibre number expression giving the icon’s opacity; overrides icon-opacity.
icon-optional boolean no MapLibre icon-optional: let the text place when the icon’s box is blocked. Default false — icon and text place as one unit.
icon-padding-expr no A MapLibre number expression (px), evaluated per feature group; overrides icon-padding-px.
icon-padding-px number (0…∞) no MapLibre icon-padding: collision-box inflation around the icon, in px. Default 2.
icon-rotate-deg number no MapLibre icon-rotate: rotation in degrees clockwise about the icon centre. Default 0.
icon-rotate-deg-expr no A MapLibre number expression (degrees clockwise); overrides icon-rotate-deg.
icon-size number (0…∞) no MapLibre icon-size: multiplier on the sprite’s authored display size (atlas pixels over its pixel ratio). Default 1.
icon-size-expr no A MapLibre number expression, evaluated per feature group; overrides icon-size.
icon-sprite string no Asset reference (@name) or literal path.
icon-text-fit none | width | height | both no MapLibre icon-text-fit: stretch the icon to the box its label occupies, on the named axes. The sprite’s stretchX/stretchY/content metadata decides which bands absorb the growth, so a shield keeps its corners; a sprite without it scales whole. The fitted box is also the icon’s collision box. Default none.
icon-text-fit-padding array of number no MapLibre icon-text-fit-padding: [top, right, bottom, left] px added around the label’s box before the icon is fitted to it. Default [0, 0, 0, 0].
ignore-placement boolean no MapLibre text-ignore-placement: don’t let this label block later ones (skip inserting its collision box). Default false.
justify auto | left | center | right no Line alignment within the wrapped block. Default auto (follows the anchor’s horizontal side).
keep-upright boolean no Flip a right-to-left label so it reads upright (MapLibre text-keep-upright). Line placement only. Default true.
layer string no Upstream feature layer name (with source). Used only to name neighbour bindings for cross-tile collision.
letter-spacing-em number no Extra advance per glyph in em. Default 0.
line-height number no Baseline-to-baseline distance in em. Default 1.2.
max-angle-deg number (0…∞) no Max cumulative bend in degrees the line may turn over a label-length window before the anchor is rejected (MapLibre text-max-angle). Line placement only. Default 45.
max-extent-px number (0…∞) no Canvas pad this node requests; labels whose bbox half-extent exceeds it are culled with a warning. Default 128.
max-width-em number (0…∞) no Wrap target width in em. Default 10; 0 disables wrapping.
max-zoom integer (0…24) no Style layer zoom gate: draw nothing above this zoom (mirrors the features node).
min-zoom integer (0…24) no Style layer zoom gate: draw nothing below this zoom (mirrors the features node).
min-zoom-field string no Per-feature min_zoom property name, reproduced for neighbour candidate filtering (mirrors the features node).
offset-em array of number no Block shift [x, y] in em, applied after anchoring. Default [0, 0].
opacity number (0…1) | $param | @node no
opacity-expr no A MapLibre number expression giving opacity, evaluated per feature group; multiplies both fill and halo alpha. Overrides the constant opacity.
outline-sdf boolean no Render outline-font glyphs through the SDF field-sampling path (maplibre-gl-js style, which draws every glyph from an SDF) instead of a per-glyph vector fill / stroke. The halo then comes from a distance threshold rather than a stroke, matching MapLibre’s halo shape and cost. SDF glyph (glyphs) stacks are unaffected. Default true.
padding-expr no A MapLibre number expression (MapLibre text-padding), evaluated per feature group; overrides the constant padding-px for that group’s collision boxes.
padding-px number (0…∞) no Collision-box inflation in px on every side. Default 2.
placement point | line | line-center no MapLibre symbol-placement. point (default) labels each feature point. line repeats labels along each polyline every spacing-px; line-center places one at each line’s arc-length midpoint. Line placement ignores wrapping (max-width-em) and lays out a single line along the path.
radial-offset number no MapLibre text-radial-offset: em distance each anchor-variants entry pushes the block away from the point in its direction. Default 0.
size number (0…∞) | $param | @node no Font size in px. Default 16.
size-expr no A MapLibre number expression (px), evaluated per feature group; overrides the constant size.
sort-key-expr no A MapLibre number expression (MapLibre symbol-sort-key), evaluated per feature group; lower values place first under collision. Absent = 0.
source string no Upstream feature source name (matches the features node). Used only to name the neighbour tile bindings for cross-tile collision. Omit to collide within this tile only.
spacing-px number (1…∞) no Gap in px between successive line anchors (MapLibre symbol-spacing). Line placement only. Default 250.
text no The label: a literal string, or a MapLibre string expression (evaluated per feature group; empty/failed → the group draws nothing).
text-optional boolean no MapLibre text-optional: let the icon place when the text’s box is blocked. Default false.
transform none | uppercase | lowercase no Case transform applied before shaping. Default none.

Draw one label layer’s placed labels: labels is the layer’s text-labels node, placement the shared label-placement node that decided it (wire the same text-labels node into both). Styling and layout live on text-labels; this node only rasterizes the winners.

Field Type Required Description
labels @node yes Reference to another node (@name).
max-extent-px number (0…∞) no Canvas pad (px) this layer’s labels need to cross a tile border un-clipped. Mirrors the text-labels field of the same name.
placement @node yes Reference to another node (@name).

Text labels (MapLibre symbol-placement): placement: point (default) labels each feature point, line / line-center walk each polyline with tangent-rotated glyphs. font is an ordered fallback stack of font and/or glyphs source names; text is a literal string or a MapLibre string expression evaluated per feature group. Paint properties have optional *-expr siblings; layout knobs are build-time constants in em. Collision is on by default and is deterministic across tiles: candidates come from this tile plus the 8 neighbour tiles (host-bound under <source>.<layer>@dx,dy), so borders stay seamless. Set source/layer (the upstream feature source) to enable neighbour gathering; without them collision is centre-tile-only. icon-name / icon-name-expr add MapLibre’s icon-image half: the icon is placed together with the text against the same index, so a symbol shows both or neither unless icon-optional / text-optional say otherwise. font and text are required unless the symbol is icon-only. Emits placement candidates instead of pixels: wire this node into a label-placement node and draw the result with text-draw.

Field Type Required Description
allow-overlap boolean no MapLibre text-allow-overlap: place the label even if it collides. It still reserves its box (blocking later labels) unless ignore-placement. Default false.
anchor center | left | right | top | bottom | top-left | top-right | bottom-left | bottom-right no Which part of the label block sits on the point (point placement). Default center.
anchor-variants array of center | left | right | top | bottom | top-left | top-right | bottom-left | bottom-right no MapLibre text-variable-anchor: anchors tried in order on collision, the first free one placed (point placement). Overrides anchor when set.
collide boolean no Whether to run deterministic label collision. Default true (MapLibre’s default). Set false to draw every label (the pre-collision behaviour).
color color | $param | @node no sRGB hex color, $param reference, or @node scalar port.
color-expr no A MapLibre color expression, evaluated per feature group; overrides the constant color.
features @node yes Reference to another node (@name).
filter-expr no The upstream features filter, reproduced when gathering neighbour candidates so they are filtered identically to this tile’s own features. Set it to whatever the features node uses.
font array of string no Ordered fallback stack of font and/or glyphs source names from the document’s sources. Outline fonts and SDF glyph stacks mix freely; the first entry covering a char shapes it. Also the default/fallback stack for font-expr and unlisted font-stacks keys.
font-expr no A MapLibre expression yielding an array of font names, evaluated per feature group (MapLibre data-driven text-font); overrides the constant font. Each result is canonicalized (names joined with ,) and looked up in font-stacks; an unlisted stack, a non-array result, or an eval error falls back to font. Every stack a host may need must be enumerable in font-stacks (wasm hosts pre-bind glyph assets).
font-stacks object no Named dynamic font stacks: canonical stack key (font names joined with ,) → ordered font/glyphs source names. Consulted by font-expr and by format text sections carrying text-font. Declaration order fixes each stack’s stable id (used by the layout cache and cross-tile collision).
halo-color color | $param | @node no sRGB hex color, $param reference, or @node scalar port.
halo-color-expr no A MapLibre color expression for the halo, evaluated per feature group; overrides the constant halo-color.
halo-width number (0…∞) | $param | @node no Halo radius in px around each glyph. Default 0 (no halo).
halo-width-expr no A MapLibre number expression (px), evaluated per feature group; overrides the constant halo-width.
icon-allow-overlap boolean no MapLibre icon-allow-overlap. A symbol carries one overlap decision, so with text present this and allow-overlap must both be set for the symbol to ignore collision. Default false.
icon-anchor center | left | right | top | bottom | top-left | top-right | bottom-left | bottom-right no Which part of the icon sits on the point (MapLibre icon-anchor). Default center.
icon-ignore-placement boolean no MapLibre icon-ignore-placement; with text present it pairs with ignore-placement the same way as the overlap flags. Default false.
icon-name string no Constant MapLibre icon-image: the sprite to draw at each point, cropped from icon-sprite. Needs icon-sprite.
icon-name-expr no A MapLibre expression naming each feature’s icon (data-driven icon-image), cropped from icon-sprite; overrides icon-name. A group resolving to an empty/unknown name draws no icon and places as a text-only symbol.
icon-offset array of number no MapLibre icon-offset: shift [x, y] in px, itself scaled by icon-size. Default [0, 0].
icon-opacity number (0…1) | $param | @node no
icon-opacity-expr no A MapLibre number expression giving the icon’s opacity; overrides icon-opacity.
icon-optional boolean no MapLibre icon-optional: let the text place when the icon’s box is blocked. Default false — icon and text place as one unit.
icon-padding-expr no A MapLibre number expression (px), evaluated per feature group; overrides icon-padding-px.
icon-padding-px number (0…∞) no MapLibre icon-padding: collision-box inflation around the icon, in px. Default 2.
icon-rotate-deg number no MapLibre icon-rotate: rotation in degrees clockwise about the icon centre. Default 0.
icon-rotate-deg-expr no A MapLibre number expression (degrees clockwise); overrides icon-rotate-deg.
icon-size number (0…∞) no MapLibre icon-size: multiplier on the sprite’s authored display size (atlas pixels over its pixel ratio). Default 1.
icon-size-expr no A MapLibre number expression, evaluated per feature group; overrides icon-size.
icon-sprite string no Asset reference (@name) or literal path.
icon-text-fit none | width | height | both no MapLibre icon-text-fit: stretch the icon to the box its label occupies, on the named axes. The sprite’s stretchX/stretchY/content metadata decides which bands absorb the growth, so a shield keeps its corners; a sprite without it scales whole. The fitted box is also the icon’s collision box. Default none.
icon-text-fit-padding array of number no MapLibre icon-text-fit-padding: [top, right, bottom, left] px added around the label’s box before the icon is fitted to it. Default [0, 0, 0, 0].
ignore-placement boolean no MapLibre text-ignore-placement: don’t let this label block later ones (skip inserting its collision box). Default false.
justify auto | left | center | right no Line alignment within the wrapped block. Default auto (follows the anchor’s horizontal side).
keep-upright boolean no Flip a right-to-left label so it reads upright (MapLibre text-keep-upright). Line placement only. Default true.
layer string no Upstream feature layer name (with source). Used only to name neighbour bindings for cross-tile collision.
letter-spacing-em number no Extra advance per glyph in em. Default 0.
line-height number no Baseline-to-baseline distance in em. Default 1.2.
max-angle-deg number (0…∞) no Max cumulative bend in degrees the line may turn over a label-length window before the anchor is rejected (MapLibre text-max-angle). Line placement only. Default 45.
max-extent-px number (0…∞) no Canvas pad this node requests; labels whose bbox half-extent exceeds it are culled with a warning. Default 128.
max-width-em number (0…∞) no Wrap target width in em. Default 10; 0 disables wrapping.
max-zoom integer (0…24) no Style layer zoom gate: draw nothing above this zoom (mirrors the features node).
min-zoom integer (0…24) no Style layer zoom gate: draw nothing below this zoom (mirrors the features node).
min-zoom-field string no Per-feature min_zoom property name, reproduced for neighbour candidate filtering (mirrors the features node).
offset-em array of number no Block shift [x, y] in em, applied after anchoring. Default [0, 0].
opacity number (0…1) | $param | @node no
opacity-expr no A MapLibre number expression giving opacity, evaluated per feature group; multiplies both fill and halo alpha. Overrides the constant opacity.
outline-sdf boolean no Render outline-font glyphs through the SDF field-sampling path (maplibre-gl-js style, which draws every glyph from an SDF) instead of a per-glyph vector fill / stroke. The halo then comes from a distance threshold rather than a stroke, matching MapLibre’s halo shape and cost. SDF glyph (glyphs) stacks are unaffected. Default true.
padding-expr no A MapLibre number expression (MapLibre text-padding), evaluated per feature group; overrides the constant padding-px for that group’s collision boxes.
padding-px number (0…∞) no Collision-box inflation in px on every side. Default 2.
placement point | line | line-center no MapLibre symbol-placement. point (default) labels each feature point. line repeats labels along each polyline every spacing-px; line-center places one at each line’s arc-length midpoint. Line placement ignores wrapping (max-width-em) and lays out a single line along the path.
radial-offset number no MapLibre text-radial-offset: em distance each anchor-variants entry pushes the block away from the point in its direction. Default 0.
size number (0…∞) | $param | @node no Font size in px. Default 16.
size-expr no A MapLibre number expression (px), evaluated per feature group; overrides the constant size.
sort-key-expr no A MapLibre number expression (MapLibre symbol-sort-key), evaluated per feature group; lower values place first under collision. Absent = 0.
source string no Upstream feature source name (matches the features node). Used only to name the neighbour tile bindings for cross-tile collision. Omit to collide within this tile only.
spacing-px number (1…∞) no Gap in px between successive line anchors (MapLibre symbol-spacing). Line placement only. Default 250.
text no The label: a literal string, or a MapLibre string expression (evaluated per feature group; empty/failed → the group draws nothing).
text-optional boolean no MapLibre text-optional: let the icon place when the text’s box is blocked. Default false.
transform none | uppercase | lowercase no Case transform applied before shaping. Default none.

Map renders on this site are made fromOpenStreetMap data viaProtomaps (© OpenStreetMap contributors), elevation from Re:Earth Terrain,Mapterhorn andEGM2008 (NGA), and aerial imagery from GSI Japan(© 国土地理院). The painterly styles use CC0 brushes byDavid Revoy.