Before writing a plugin, check whether a render-only
override or an
existing geom composed differently gets you there. A new geom is the right
tool for a genuinely new shape, not a restyle of an existing one.
One array, both halves
Everything you add is registered through a singleplugins array. Passing it once seeds two things at once — what you can write (the typed builder methods) and what can compile and render — so the authoring surface and the runtime can never drift apart.
LollipopGeom is the compile half; the object literal is the render contract. A stat or a transform has no render half, so it goes into the same array on its own.
Two entry points
react-renderer
The ergonomic one. Returns the typed builder (
geom / stat / transform /
scale / coord / createSpec / pipe) and a GraphProvider already
bound to the same plugins. Reach for this in a React app.viz-engine
The primitives
createGraphyKit wraps. Use createGraphyBuilder({ plugins }) for the headless authoring surface and
pass the same array to <GraphProvider plugins={...}>. Choose this for framework-agnostic or advanced wiring.plugins array. The kit is pure sugar — it calls createGraphyBuilder and pre-binds a provider, nothing more.
What you can add
A geom has two halves because it both places observations (compile) and paints them (render). Stats and transforms only touch data, so they’re compile-only — no renderer. A stat is a
Stat subclass, a transform a TransformStrategy object; each goes into plugins on its own and earns a typed builder method (kit.stat.<type>(), kit.transform.<transformType>()) beside the built-in statistics and transforms.
Slots
Replace a region’s render — no plugin, no geom.
Custom geoms
Define a new shape with
Geom — position roles, aesthetics, and the compile
step.Geom renderers
defineGeomRenderer, render-only overrides, hit-testing, and hover.Statistics
The layer-scoped summaries a
stat computes — the vocabulary a custom
Stat joins.Transforms
The dataset reshapings a
transform applies — the vocabulary a custom
TransformStrategy joins.Diagnostics
A plugin mistake surfaces as aVizDiagnostic rather than a throw, so the chart keeps rendering around it. All but one are warnings, and several are the only signal that an otherwise-silent plugin is broken — read them before reaching for a debugger.
Some are computed once, when the provider reads the
plugins array; the rest are recomputed per compile, since they depend on what a layer actually compiled to.
Related
- How a chart is built — the pipeline your plugin joins
- Rendering — the renderer that hosts slots and geom renderers

