> ## Documentation Index
> Fetch the complete documentation index at: https://docs.graphy.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Extending

The engine ships with a fixed set of built-in geoms, stats, and transforms — but the grammar is open. You can register your own and they become first-class: a typed builder method, compiled through the same pipeline, painted through the same renderer registry. This is the advanced surface; most charts never need it.

There are two ways in. **Plugins** extend the grammar itself — new geoms, stats, and transforms that compile and render like the built-ins. **Slots** are lighter: they replace how one *region* of the chart renders (a header, legend, or tooltip) without touching the grammar. Most of this section is about plugins; slots are a self-contained escape hatch on the renderer.

<Note>
  Before writing a plugin, check whether a [render-only
  override](/sdk-next/extending/geom-renderers#render-only-overrides) 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.
</Note>

## One array, both halves

Everything you add is registered through a single `plugins` 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.

```tsx theme={null}
import { createGraphyKit, defineGeomRenderer } from '@graphysdk/react-renderer';

const lollipop = defineGeomRenderer(new LollipopGeom(), lollipopRenderer);

const kit = createGraphyKit({ plugins: [lollipop] });
// kit.geom.lollipop(...) now exists and is typed from the definition
```

## Two entry points

<ParamField path="createGraphyKit" type="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.
</ParamField>

<ParamField path="createGraphyBuilder + <GraphProvider plugins>" type="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.
</ParamField>

Both take the same `plugins` array. The kit is pure sugar — it calls `createGraphyBuilder` and pre-binds a provider, nothing more.

## What you can add

| Extension                | Adds                                      | Halves                                                     |
| ------------------------ | ----------------------------------------- | ---------------------------------------------------------- |
| **Custom geom**          | A new kind of shape                       | Compile half (`Geom`) + render half (`defineGeomRenderer`) |
| **Render-only override** | A restyle of a built-in geom's paint      | Render half only — geometry unchanged                      |
| **Custom stat**          | A per-layer data reshaping before mapping | Compile half only                                          |
| **Custom transform**     | A dataset reshaping                       | Compile half only                                          |

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.

<CardGroup cols={2}>
  <Card title="Slots" icon="puzzle-piece" href="/sdk-next/extending/slots">
    Replace a region's render — no plugin, no geom.
  </Card>

  <Card title="Custom geoms" icon="shapes" href="/sdk-next/extending/custom-geoms">
    Define a new shape with `Geom` — position roles, aesthetics, and the compile
    step.
  </Card>

  <Card title="Geom renderers" icon="paintbrush" href="/sdk-next/extending/geom-renderers">
    `defineGeomRenderer`, render-only overrides, hit-testing, and hover.
  </Card>

  <Card title="Custom stats" icon="calculator" href="/sdk-next/extending/custom-stats">
    A layer-scoped data reshaping that runs before mapping.
  </Card>

  <Card title="Custom transforms" icon="table" href="/sdk-next/extending/custom-transforms">
    Reshape the dataset before it becomes a layer.
  </Card>
</CardGroup>

## Related

* [How a chart is built](/sdk-next/concepts/how-a-chart-is-built) — the pipeline your plugin joins
* [Rendering](/sdk-next/rendering/index) — the renderer that hosts slots and geom renderers
