chat

$npx mdskill add vercel-labs/json-render/chat

Renders json-render specs as Chat SDK `CardElement` objects. Each Chat SDK adapter converts the card to its platform format.

SKILL.md

.github/skills/chatView on GitHub ↗
---
name: chat
description: Chat SDK renderer for json-render that turns JSON specs into native chat cards (Block Kit on Slack, Adaptive Cards on Teams, and the card format of other Chat SDK adapters). Use when working with @json-render/chat, building bots that post rich messages with tables, charts, fields, or buttons, streaming a generated card into a chat thread, or when the user mentions Chat SDK, Slack Block Kit, or Teams Adaptive Cards together with json-render.
metadata:
  tags: chat, chat-sdk, slack, block-kit, teams, adaptive-cards, discord, json-render
---

# @json-render/chat

Renders json-render specs as Chat SDK `CardElement` objects. Each Chat SDK adapter converts the card to its platform format.

## Quick start

```typescript
import { defineCatalog } from "@json-render/core";
import {
  schema,
  standardComponentDefinitions,
  streamCard,
} from "@json-render/chat";
import { streamText } from "ai";

const catalog = defineCatalog(schema, {
  components: standardComponentDefinitions,
});

chat.onNewMention(async (thread, message) => {
  const result = streamText({
    model: "anthropic/claude-haiku-4.5",
    system: catalog.prompt(),
    prompt: message.text,
  });
  await streamCard(thread, result.textStream);
});
```

`streamCard(target, textStream, options)` posts the card once the root exists, edits it every `updateIntervalMs` (default 500) as elements arrive, and finishes with a validated card. `toCard(spec, options)` converts a complete spec. `toPartialCard(spec)` returns a best-effort card for a streaming spec, or `null` before the root exists.

## Spec structure

Same flat tree as other renderers: `root` plus `elements`, with optional `state`. The root must be a `Card`. An inner `Card` renders as a titled section, because chat cards cannot nest.

Standard components: `Card`, `Section`, `Text` (markdown), `Fields` with `Field`, `Table`, `Chart` (`pie` with `segments`, or `bar`, `line`, `area` with `categories` and `series[].values`), `Divider`, `Image`, and `Actions` with `Button` and `LinkButton`.

```json
{
  "root": "card",
  "elements": {
    "card": {
      "type": "Card",
      "props": { "title": "Weekly deploys" },
      "children": ["kpis", "chart"]
    },
    "kpis": { "type": "Fields", "props": {}, "children": ["total"] },
    "total": {
      "type": "Field",
      "props": { "label": "Deploys", "value": "985" },
      "children": []
    },
    "chart": {
      "type": "Chart",
      "props": {
        "title": "Deploys per day",
        "chart": {
          "type": "bar",
          "categories": ["Mon", "Tue"],
          "series": [{ "name": "Deploys", "values": [180, 210] }]
        }
      },
      "children": []
    }
  }
}
```

## State, repeat, and visibility

`$state`, `$item`, `$index`, and `$template` resolve against `spec.state`. `visible` conditions drop elements. `repeat` renders an element's children once per item. A repeated `Table` expands its rows as a template, and object rows map to headers by key name. `$bindState` and `$bindItem` have no effect because posted messages have no inputs. Expansion stops at `maxElements` (default 1000 elements and table rows); `toCard` throws past it.

## Validation and limits

`toCard` throws `CardSpecError` with an `issues` array (one entry per problem). Send the issues back to the model to repair the spec. Pass `limits` to reject specs that a platform would degrade, for example `{ tables: 1, charts: 2 }` for Slack. Available limits: `tables`, `charts`, `fields`, `tableRows`, `tableColumns`, `chartTitle`, `chartLabel`, `chartSeries`, `chartPoints`.

## Runtime

The renderer imports `chat` for types only, so it runs in the browser and on the server. Convert a card for a specific platform with the adapter, for example `cardToSlackBlocks` from `@chat-adapter/slack/blocks` or `cardToAdaptiveCard` from `@chat-adapter/teams/cards`.

More from vercel-labs/json-render

SkillDescription
codegenCode generation utilities for json-render. Use when generating code from UI specs, building custom code exporters, traversing specs, or serializing props for @json-render/codegen.
devtoolsDrop-in inspector panel for any json-render app. Use when the user wants to debug a generative UI, inspect the spec tree, edit state at runtime, see dispatched actions, follow stream patches live, browse a catalog, or pick DOM elements to find their spec keys. Triggers include "add devtools", "debug json-render", "inspect the spec", "why is this element not rendering", "see the state at runtime", or requests to tap streams / capture action logs for `@json-render/devtools`.
devtools-reactReact adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot @json-render/devtools-react in a React json-render app, including spec inspection, state editing, action and stream timelines, catalog browsing, or DOM picking.
devtools-solidSolidJS adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot @json-render/devtools-solid in a SolidJS json-render app, including spec inspection, state editing, action and stream timelines, catalog browsing, or DOM picking.
devtools-svelteSvelte 5 adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot @json-render/devtools-svelte in a Svelte json-render app, including spec inspection, state editing, action and stream timelines, catalog browsing, or DOM picking.
devtools-vueVue adapter for the json-render devtools inspector. Use whenever the user wants to add, configure, or troubleshoot @json-render/devtools-vue in a Vue json-render app, including spec inspection, state editing, action and stream timelines, catalog browsing, or DOM picking.
directivesPre-built custom directives for json-render — formatting, math, string manipulation, and i18n. Use when working with @json-render/directives, defining custom directives with defineDirective, or adding $format, $math, $concat, $count, $truncate, $pluralize, $join, or $t to specs.
imageImage renderer for json-render that turns JSON specs into SVG and PNG images via Satori. Use when working with @json-render/image, generating OG images from JSON, creating social cards, or rendering AI-generated image specs.
inkInk terminal renderer for json-render that turns JSON specs into interactive terminal UIs. Use when working with @json-render/ink, building terminal UIs from JSON, creating terminal component catalogs, or rendering AI-generated specs in the terminal.
jotaiJotai adapter for json-render's StateStore interface. Use when integrating json-render with Jotai for state management via @json-render/jotai.