npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@tambo-ai/react

v0.67.1

Published

React client package for Tambo AI

Downloads

5,708

Readme


What is Tambo?

Tambo is a generative UI SDK for React. Register your components, and the AI decides which ones to render based on natural language conversations.

Why We Built This

Most software is built around a one-size-fits-all mental model that doesn't fit every user.

Users shouldn't have to learn your app. Generative UI shows the right components based on what someone is trying to do. First-time users and power users see different things.

Users shouldn't have to click through your workflows. "Show me sales from last quarter grouped by region" should just work. The AI translates what users want into the right interface.

const components: TamboComponent[] = [{
  name: "Graph",
  description: "Displays data as charts",
  component: Graph,
  propsSchema: z.object({ data: z.array(...), type: z.enum(["line", "bar", "pie"]) })
}];

Key Benefits

  • No AI Expertise Needed - If you can write React, you can build generative UIs
  • MCP-Native Architecture - Built-in Model Context Protocol support
  • Bring Your Own LLM - Works with OpenAI, Anthropic, Google, Mistral, or any OpenAI-compatible provider
  • Dual Build Output - CommonJS and ESM modules for broad compatibility
  • Type-Safe - Full TypeScript support with Zod schemas

Installation

Create New App

npx tambo create-app my-tambo-app
cd my-tambo-app
npm run dev

Add to Existing Project

npm install @tambo-ai/react
# or
yarn add @tambo-ai/react

Then initialize:

npx tambo init

Quick Start

import {
  TamboProvider,
  useTamboThread,
  useTamboThreadInput,
} from "@tambo-ai/react";
import { z } from "zod/v4";

// 1. Register your components
const components = [
  {
    name: "Graph",
    description: "Displays data as charts (bar, line, pie)",
    component: Graph,
    propsSchema: z.object({
      data: z.array(z.object({ name: z.string(), value: z.number() })),
      type: z.enum(["line", "bar", "pie"]),
    }),
  },
];

// 2. Wrap your app
function App() {
  return (
    <TamboProvider
      apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}
      components={components}
    >
      <ChatInterface />
    </TamboProvider>
  );
}

// 3. Use hooks to build your UI
function ChatInterface() {
  const { thread } = useTamboThread();
  const { value, setValue, submit, isPending } = useTamboThreadInput();

  return (
    <div>
      {thread.messages.map((message) => (
        <div key={message.id}>
          {Array.isArray(message.content) ? (
            message.content.map((part, i) =>
              part.type === "text" ? <p key={i}>{part.text}</p> : null,
            )
          ) : (
            <p>{String(message.content)}</p>
          )}
          {message.renderedComponent}
        </div>
      ))}
      <input value={value} onChange={(e) => setValue(e.target.value)} />
      <button onClick={() => submit()} disabled={isPending}>
        Send
      </button>
    </div>
  );
}

→ Full tutorial

Core Concepts

Component Registration

Register React components with Zod schemas for type-safe props:

import { type TamboComponent } from "@tambo-ai/react";

const components: TamboComponent[] = [
  {
    name: "WeatherCard",
    description: "Displays weather information with temperature and conditions",
    component: WeatherCard,
    propsSchema: z.object({
      location: z.string(),
      temperature: z.number(),
      condition: z.string(),
    }),
  },
];

→ Learn more about components

Provider Setup

Wrap your app with TamboProvider to enable AI capabilities:

<TamboProvider
  apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}
  components={components}
  tools={tools} // optional
  userToken={userToken} // optional
>
  <YourApp />
</TamboProvider>

→ See all provider options

Hooks

| Hook | Description | | -------------------------- | -------------------------------------------------- | | useTamboThread() | Access current thread and messages | | useTamboThreadInput() | Handle user input and message submission | | useTamboCurrentMessage() | Access current message context (inside components) | | useTamboComponentState() | Persistent component state across renders | | useTamboStreamStatus() | Monitor streaming status for progressive loading | | useTamboSuggestions() | Generate contextual suggestions |

→ API Reference

Key Features

Generative Components

Generative components render once in response to a message. Charts, summaries, data visualizations.

const components: TamboComponent[] = [
  {
    name: "Graph",
    description: "Displays data as charts",
    component: Graph,
    propsSchema: z.object({
      data: z.array(z.object({ name: z.string(), value: z.number() })),
      type: z.enum(["line", "bar", "pie"]),
    }),
  },
];

→ Learn more about components

Interactable Components

Interactable components persist and update as users refine requests. Shopping carts, spreadsheets, task boards.

import { withInteractable } from "@tambo-ai/react";

const InteractableNote = withInteractable(Note, {
  componentName: "Note",
  description: "A note supporting title, content, and color modifications",
  propsSchema: z.object({
    title: z.string(),
    content: z.string(),
    color: z.enum(["white", "yellow", "blue", "green"]).optional(),
  }),
});

// Pre-place in your UI or let AI generate dynamically
<InteractableNote id="note-1" title="My Note" content="Content here" />;

→ Learn more about interactable components

MCP Integration

Connect to Linear, Slack, databases, or your own MCP servers. Tambo supports the full MCP protocol: tools, prompts, elicitations, and sampling.

import { TamboMcpProvider, MCPTransport } from "@tambo-ai/react/mcp";

const mcpServers = [
  {
    name: "filesystem",
    url: "http://localhost:3001/mcp",
    transport: MCPTransport.HTTP,
  },
];

<TamboProvider components={components} mcpServers={mcpServers}>
  <TamboMcpProvider>
    <App />
  </TamboMcpProvider>
</TamboProvider>;

→ Learn more about MCP

Dependency note

The @tambo-ai/react/mcp subpath declares @modelcontextprotocol/sdk, zod, and zod-to-json-schema as optional peer dependencies. If you import this MCP entrypoint in your app, make sure these packages are installed with compatible versions:

npm install @modelcontextprotocol/sdk@^1.24.0 zod@^4.0.0 zod-to-json-schema@^3.25.0

zod can also be ^3.25 if you prefer Zod 3; both ^3.25 and ^4.0 satisfy the SDK's zod/v3 subpath constraints.

Local Tools

Sometimes you need functions that run in the browser. DOM manipulation, authenticated fetches, accessing React state. Define them as tools and the AI can call them.

import { z } from "zod/v4";
import { defineTool } from "@tambo-ai/react";

const tools = [
  defineTool({
    name: "getWeather",
    description: "Fetches weather data for a location",
    tool: async ({ location }) =>
      fetch(`/api/weather?q=${location}`).then((r) => r.json()),
    inputSchema: z.object({
      location: z.string(),
    }),
    outputSchema: z.object({
      temperature: z.number(),
      condition: z.string(),
      location: z.string(),
    }),
  }),
];

<TamboProvider tools={tools} components={components}>
  <App />
</TamboProvider>;

→ Learn more about tools

Advanced: Transforming Tool Responses

For tools that return rich content (images, audio, mixed media), provide a transformToContent function:

const tools: TamboTool[] = [
  {
    name: "getImageData",
    description: "Fetches image data with metadata",
    tool: async (imageId: string) => {
      const data = await fetchImageData(imageId);
      return { url: data.imageUrl, description: data.description };
    },
    toolSchema: z.function({
      input: z.string(),
      output: z.object({ url: z.string(), description: z.string() }),
    }),
    transformToContent: (result) => [
      { type: "text", text: result.description },
      { type: "image_url", image_url: { url: result.url } },
    ],
  },
];

The MCP integration automatically uses transformToContent to pass through rich content.

Local Resources

Resources provide context to the AI by making content accessible without requiring a full MCP server. You can register static resources, dynamic resource functions, or both.

Static Resources

Register individual resources directly in your provider:

import { type ListResourceItem } from "@tambo-ai/react";

const resources: ListResourceItem[] = [
  {
    uri: "file:///config/app-settings.json",
    name: "App Settings",
    description: "Current application configuration",
    mimeType: "application/json",
  },
  {
    uri: "file:///docs/user-guide.md",
    name: "User Guide",
    description: "Getting started documentation",
    mimeType: "text/markdown",
  },
];

<TamboProvider resources={resources}>
  <App />
</TamboProvider>;

Dynamic Resources

For resources that need to be fetched or computed at runtime, provide listResources and getResource functions:

import { type ResourceSource, type ReadResourceResult } from "@tambo-ai/react";

const listResources = async (search?: string) => {
  const allDocs = await fetchUserDocuments();
  return allDocs
    .filter((doc) => !search || doc.name.includes(search))
    .map((doc) => ({
      uri: `file:///docs/${doc.id}`,
      name: doc.name,
      description: doc.summary,
      mimeType: "text/markdown",
    }));
};

const getResource = async (uri: string): Promise<ReadResourceResult> => {
  const docId = uri.split("/").pop();
  const content = await fetchDocumentContent(docId);
  return {
    contents: [
      {
        uri,
        mimeType: "text/markdown",
        text: content,
      },
    ],
  };
};

<TamboProvider listResources={listResources} getResource={getResource}>
  <App />
</TamboProvider>;

Important: Both listResources and getResource must be provided together - you cannot provide one without the other.

Programmatic Registration

You can also register resources programmatically:

const { registerResource, registerResourceSource } = useTamboRegistry();

// Register a single resource
registerResource({
  uri: "file:///runtime/state.json",
  name: "Application State",
  mimeType: "application/json",
});

// Register a dynamic source
registerResourceSource({
  listResources: async () => [...],
  getResource: async (uri) => ({ contents: [...] }),
});

Resource vs MCP Server

  • Local resources: Fast, simple, runs in the browser. Great for app state, config, cached data.
  • MCP servers: Full protocol support, server-side execution. Use for databases, APIs, external services.

Local resources appear in useTamboMcpResourceList() alongside MCP resources, with MCP resources always prefixed by their serverKey.

→ Learn more about resources

Streaming Status

Monitor streaming status for progressive loading:

import { useTamboStreamStatus } from "@tambo-ai/react";

function LoadingComponent({ title, data }) {
  const { streamStatus, propStatus } = useTamboStreamStatus();

  // Show spinner until complete
  if (!streamStatus.isSuccess) return <Spinner />;

  // Or show each prop as it arrives
  return (
    <div>
      {propStatus["title"]?.isSuccess && <h3>{title}</h3>}
      {propStatus["data"]?.isSuccess && <Chart data={data} />}
    </div>
  );
}

→ Learn more about streaming

Context, Auth, and Suggestions

Additional context lets you pass metadata to give the AI better responses. User state, app settings, current page. User authentication passes tokens from your auth provider. Suggestions generates prompts users can click based on what they're doing.

<TamboProvider
  userToken={userToken}
  contextHelpers={{
    selectedItems: () => ({
      key: "selectedItems",
      value: selectedItems.map((i) => i.name).join(", "),
    }),
    currentPage: () => ({ key: "page", value: window.location.pathname }),
  }}
/>
const { suggestions, accept } = useTamboSuggestions({ maxSuggestions: 3 });

suggestions.map((s) => (
  <button key={s.id} onClick={() => accept(s)}>
    {s.title}
  </button>
));

→ Learn moreUser authenticationSuggestions

Supported LLM Providers

OpenAI, Anthropic, Google Gemini, Mistral, Groq, and any OpenAI-compatible provider. Full list. Missing one? Let us know.

When to Use This SDK

Use @tambo-ai/react directly when you need:

  • Custom implementations - Build your own chat interface or UI patterns
  • Existing design systems - Integrate with your component library
  • Fine-grained control - Customize rendering, state, and behavior
  • Non-Next.js frameworks - Works with any React setup

For quick starts with pre-built components, use:

  • npx tambo create-app - Full-featured template with UI components
  • Tambo UI Library - Copy/paste production-ready components

Build Output

This package provides dual build outputs for broad compatibility:

  • CommonJS (dist/) - For Node.js and older bundlers
  • ESM (esm/) - For modern bundlers and native ES modules

TypeScript definitions included for both outputs.

Community & Support

Documentation

License

MIT License - see LICENSE for details.


Note for AI/LLM agents: For comprehensive documentation in a format optimized for language models, visit docs.tambo.co/llms.txt