Skip to main content
A geom is what a chart draws for its data — a line, a bar, a point. Each geom is a layer in the spec; add several and they stack into one chart. Geoms are the visible half of the grammar: mappings and scales decide where things go, geoms decide what is drawn there.

The built-in geoms

Each is a factory that returns a layer. Call it with options to configure the layer, and geom-specific params for its geometry and behavior knobs — paint (colors, widths, opacities) lives in the stylesheet instead:

Params and paint, geom by geom

params are geometry and behaviour; the style.* target beside them is where that geom’s paint is authored. Every target also takes the shared color, alpha and saturation. Two things catch people out: a bar’s borderRadius is a token ('none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'full'), not a pixel count; and a defaults entry loses to a mapped aesthetic while an overrides entry beats it. Styling has the full cascade.
Params merge without validation, so a key a geom doesn’t declare is accepted and quietly ignored.

Layers

Every geom.*() you pipe in adds a layer, drawn in order — later layers sit on top. Layers share the spec-level mapping unless one overrides it. This is how decorated and combo charts are built:

Common layer options

Beyond params, every geom accepts these options:

Position modes

When several observations share the same x (because color or group splits the data), a layer’s position decides how they arrange: Each geom picks its own default: geom.bar() is 'dodge', geom.area() is 'stack', and geom.point(), geom.line(), geom.rule() and geom.tile() are 'identity'. So a bar chart with a color mapping arrives grouped and an area chart arrives stacked, with no position of your own.

Next