components
SKILL.md
Tambo Components
Two component types: generative (AI creates on-demand) and interactable (pre-placed, AI updates).
Quick Start
// Generative: AI creates when needed
const components: TamboComponent[] = [
{
name: "WeatherCard",
component: WeatherCard,
description: "Shows weather. Use when user asks about weather.",
propsSchema: z.object({ city: z.string(), temp: z.number() }),
},
];
<TamboProvider components={components}>
<App />
</TamboProvider>;
Generative Components
AI dynamically selects and renders these in response to user messages.
import { TamboProvider, TamboComponent } from "@tambo-ai/react";
import { z } from "zod";
const WeatherCardSchema = z.object({
city: z.string().describe("City name"),
temperature: z.number().describe("Temperature in Celsius"),
condition: z.string().describe("Weather condition"),
});
const components: TamboComponent[] = [
{
name: "WeatherCard",
component: WeatherCard,
description:
"Displays weather for a city. Use when user asks about weather.",
propsSchema: WeatherCardSchema,
},
];
<TamboProvider apiKey={apiKey} components={components}>
<App />
</TamboProvider>;
Rendering Generative Components
Use ComponentRenderer to render AI-generated components in your message list:
import { ComponentRenderer } from "@tambo-ai/react";
function Message({
message,
threadId,
}: {
message: TamboThreadMessage;
threadId: string;
}) {
return (
<div>
{message.content.map((block) => {
switch (block.type) {
case "text":
return <p key={`${message.id}:text`}>{block.text}</p>;
case "component":
return (
<ComponentRenderer
key={block.id}
content={block}
threadId={threadId}
messageId={message.id}
/>
);
default:
return null;
}
})}
</div>
);
}
Generative Key Points
- propsSchema: Zod object with
.describe()on each field - description: Tells AI when to use the component
- Streaming: Props start
undefined, make them optional or handle gracefully - Use
z.infer<typeof Schema>for TypeScript props type
Interactable Components
Pre-place in your UI; AI can observe and update props via natural language.
import { withTamboInteractable } from "@tambo-ai/react";
import { z } from "zod";
const NoteSchema = z.object({
title: z.string().describe("Note title"),
content: z.string().describe("Note content"),
color: z.enum(["white", "yellow", "blue"]).optional(),
});
function Note({ title, content, color = "white" }: Props) {
return (
<div style={{ backgroundColor: color }}>
<h3>{title}</h3>
<p>{content}</p>
</div>
);
}
export const InteractableNote = withTamboInteractable(Note, {
componentName: "Note",
description: "A note with editable title, content, and color",
propsSchema: NoteSchema,
});
Interactable How It Works
- Auto-registration: Component registers when mounted
- Context sending: Current props automatically visible to AI
- Tool registration: Update tools registered automatically
- Bidirectional: User edits and AI updates both work
When to Use Each
| Generative | Interactable |
|---|---|
| AI creates on-demand | You pre-place in UI |
| One-time render | Persistent across session |
| Props generated once | AI can update props |
| Chat responses, dashboards | Settings, forms, task boards |
Weekly Installs
99
Repository
tambo-ai/tamboGitHub Stars
11.1K
First Seen
Feb 5, 2026
Security Audits
Installed on
gemini-cli96
opencode96
codex95
github-copilot93
kimi-cli89
amp89