# How to Register React Components for LLM Use with Tambo AI

> Learn how Tambo AI registers React components for LLM use. Tambo AI's runtime registry validates metadata and converts props schemas for seamless integration.

- Repository: [tambo ai/tambo](https://github.com/tambo-ai/tambo)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Tambo AI enables large language models to render React UI by exposing components through a runtime registry that validates metadata, converts props schemas to JSON-Schema, and provides registration APIs via the TamboRegistryProvider.**

Tambo AI is an open-source React SDK that bridges the gap between conversational AI and interactive user interfaces. To register React components for LLM use, developers define component metadata with typed props schemas and pass them through the SDK's validation pipeline, which prepares the components for AI-driven rendering at runtime.

## The Component Registration Pipeline

The registration flow consists of three distinct stages that transform a React component into an LLM-accessible UI element:

1. **Definition** – Describe the component with metadata, props schema, and optional loading states
2. **Validation** – Verify the schema, convert it to JSON-Schema, and check for forbidden types
3. **Storage** – Add the validated component to the runtime registry and associate any tools

This pipeline is implemented across [`react-sdk/src/model/component-metadata.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/model/component-metadata.ts), [`react-sdk/src/util/registry-validators.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/util/registry-validators.ts), and [`react-sdk/src/providers/tambo-registry-provider.tsx`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/providers/tambo-registry-provider.tsx).

## Step 1: Define a TamboComponent with Props Schema

Components must conform to the `TamboComponent` interface defined in [`react-sdk/src/model/component-metadata.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/model/component-metadata.ts). This structure requires a **name**, **description**, the React **component** itself, an optional **loadingComponent**, and a **props schema**.

The `propsSchema` accepts Zod, Valibot, or similar schema definitions, which the SDK converts to JSON-Schema for the LLM:

```typescript
// src/components/MyButton.tsx
import { TamboComponent } from "@tambo-ai/react";
import { z } from "zod";

export const myButton: TamboComponent = {
  name: "MyButton",
  description: "A simple button used in chat UI that triggers an action when clicked",
  component: (props: { label: string; onClick: () => void }) => (
    <button onClick={props.onClick}>{props.label}</button>
  ),
  loadingComponent: () => <div>Loading button…</div>,
  propsSchema: z.object({
    label: z.string().describe("The text displayed on the button"),
    onClick: z.function().describe("Callback fired when the button is clicked"),
  }),
};

```

The `propsSchema` is mandatory. If omitted, the validation step will throw an error preventing registration.

## Step 2: Validate and Prepare the Component

Before a component enters the registry, `validateAndPrepareComponent` in [`react-sdk/src/util/registry-validators.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/util/registry-validators.ts) performs several critical checks:

- **Name validation** – Ensures the component name is unique and follows naming conventions
- **Schema conversion** – Transforms Zod/Valibot schemas into standard JSON-Schema using internal converters
- **Type restrictions** – Forbids record types (`Record<string, any>`) in props schemas to prevent ambiguous LLM outputs
- **Deprecation handling** – Migrates legacy `propsDefinition` to the modern `propsSchema` format

If validation fails, the function throws immediately, preventing malformed components from reaching the LLM context window.

## Step 3: Register Components at Runtime

The `TamboRegistryProvider` in [`react-sdk/src/providers/tambo-registry-provider.tsx`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/providers/tambo-registry-provider.tsx) maintains the component registry as React state (`componentList`). It exposes the `registerComponent` function through the `TamboRegistryContext`, which developers can access via the `useTambo` hook.

### Static Registration via Provider

For applications with known component sets, pass an array to the `components` prop:

```tsx
import { TamboRegistryProvider } from "@tambo-ai/react";
import { myButton } from "./components/MyButton";
import { dataCard } from "./components/DataCard";

export default function App() {
  return (
    <TamboRegistryProvider components={[myButton, dataCard]}>
      <YourApp />
    </TamboRegistryProvider>
  );
}

```

The provider registers these components once during mount using a `useEffect` hook.

### Dynamic Registration via Hook

For lazy-loaded or conditional components, use the `useTambo` hook:

```tsx
import { useTambo } from "@tambo-ai/react";
import { useEffect, useCallback } from "react";
import { myButton } from "@/components/MyButton";

export function ChatInterface() {
  const { registerComponent } = useTambo();

  const doRegister = useCallback(() => {
    registerComponent(myButton, false); // false suppresses overwrite warnings
  }, [registerComponent]);

  useEffect(() => {
    doRegister();
  }, [doRegister]);

  return <div>Chat interface with LLM-rendered components</div>;
}

```

### Tool Associations

Components can bundle related tools using the `associatedTools` property. When registered, the provider automatically calls `registerTools` and updates `componentToolAssociations` state, creating a bidirectional mapping between components and their capabilities:

```tsx
const myButton: TamboComponent = {
  name: "MyButton",
  // ... other properties
  associatedTools: [fetchUserDataTool, updateStatusTool],
};

```

## How the LLM Discovers Registered Components

The SDK serializes the registry for LLM consumption via [`react-sdk/src/v1/utils/registry-conversion.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/v1/utils/registry-conversion.ts). The `toAvailableComponents` function converts the internal `ComponentRegistry` map into a JSON payload containing component names, descriptions, and JSON-Schema definitions for props:

```typescript
// Simplified from registry-conversion.ts
export const toAvailableComponents = (registry: ComponentRegistry) => {
  return Object.values(registry).map((component) => ({
    name: component.name,
    description: component.description,
    propsSchema: component.props, // JSON-Schema format
  }));
};

```

This payload is sent to the Tambo AI server with each message, allowing the LLM to select appropriate components by name and generate valid props that conform to the schema.

## Summary

- **Tambo AI** exposes React components to LLMs through a runtime registry system defined in [`react-sdk/src/providers/tambo-registry-provider.tsx`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/providers/tambo-registry-provider.tsx).
- **Component definitions** require a `TamboComponent` interface with `name`, `description`, `component`, and `propsSchema` (Zod/Valibot supported).
- **Validation** occurs in [`react-sdk/src/util/registry-validators.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/util/registry-validators.ts), which converts schemas to JSON-Schema and forbids ambiguous record types.
- **Registration** can be static via `TamboRegistryProvider` or dynamic via the `useTambo` hook, with optional `associatedTools` for component-tool binding.
- **LLM discovery** happens through serialization in [`react-sdk/src/v1/utils/registry-conversion.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/v1/utils/registry-conversion.ts), sending JSON-Schema metadata to the AI for component selection.

## Frequently Asked Questions

### What schema libraries does Tambo AI support for component props?

Tambo AI accepts Zod, Valibot, and similar schema definition libraries through the `propsSchema` property. The `validateAndPrepareComponent` function in [`react-sdk/src/util/registry-validators.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/util/registry-validators.ts) automatically converts these schemas to standard JSON-Schema format before sending them to the LLM, ensuring compatibility with the AI's structured output capabilities.

### Can I register components dynamically after the app has mounted?

Yes, you can register components dynamically using the `useTambo` hook. The hook exposes the `registerComponent` function from the `TamboRegistryContext`, allowing you to add components inside `useEffect` hooks or event handlers. Pass `false` as the second argument to suppress console warnings when overwriting existing component registrations during hot reloading or iterative updates.

### How does Tambo AI associate tools with specific components?

Components can declare `associatedTools` in their `TamboComponent` definition. When `registerComponent` detects these tools, it automatically calls `registerTools` and updates the internal `componentToolAssociations` state map. This creates a bidirectional relationship where the LLM knows which tools are available for specific UI components, and the system can route tool calls to the appropriate component context.

### What happens if a component's props schema uses TypeScript record types?

The validation layer in [`react-sdk/src/util/registry-validators.ts`](https://github.com/tambo-ai/tambo/blob/main/react-sdk/src/util/registry-validators.ts) explicitly forbids record types (`Record<string, any>`) in props schemas. If detected, `validateAndPrepareComponent` will throw an error preventing registration. This restriction prevents ambiguous type definitions that could confuse the LLM's structured output generation, ensuring that all props can be accurately described by JSON-Schema.