Reference

Components.

Every component the runtime ships with, as a live tile you can scan. Filter by category or search by what you want to build — “table”, “chart”, “upload”, “alert” — then open a tile for its signature, its props, and the source behind the preview.

Loading the component gallery…

How a call is written

Every component takes one of three call shapes: the canonical Comp(positional, { props }), all‑positional in the order the props are listed, or a single all‑named { } object. Props marked optional can be omitted or passed as null, enum values are case‑sensitive quoted strings, and the spacing props (gap/padding/margin) share one scale: none | 3xs | 2xs | xs | sm | md | lg | xl | 2xl | 3xl.

Adding your own

Pass ComponentSpec objects to el.registerComponents([...]). Each spec declares the source signature and a renderer that returns a DOM node, and the new component shows up in the next getSystemPrompt() call automatically.

const ProductTile = {
  name: "ProductTile",
  description: "Product tile with title, price, and CTA.",
  props: [
    { name: "title", type: "string" },
    { name: "price", type: "number" },
    { name: "variant", type: "string", optional: true, enum: ["default", "featured"] },
    { name: "cta", type: "Action", optional: true },
  ],
  render: (_node, props) => {
    const card = document.createElement("div");
    card.className = "product";
    card.textContent = `${props.title} — $${props.price}`;
    return card;
  },
};

el.registerComponents([ProductTile]);

In‑program function MyCard(...) { return ... } declarations may not reuse a built‑in name — the validator flags the collision — unless the body calls that same name. That is the wrapper pattern: inside its own body the name still refers to the built‑in, so function Badge(l) { return Badge(l, { tone: "success" }) } extends the library Badge instead of recursing. Full guide →

Next