Tambo AI: a React SDK where the agent renders your own components
Generative UI SDK for React
At a glance
- What is it?
- Tambo registers React components with Zod schemas, turns those schemas into LLM tool definitions, and streams generated props back into your UI. It ships a hosted backend or a Docker self-host path, and it is a poor fit if you want the model to write arbitrary markup.
- Who is it for?
- Adopt Tambo if you already have a React component library and want an agent to select and populate those components rather than emit markup you have to sanitize. Skip it if you need framework-agnostic output, or if you cannot run a backend, because the SDK depends on a conversation service you either pay for through Tambo Cloud or operate yourself from docker-compose.yml.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem Tambo solves: an agent that picks your components instead of writing markup
Most chat integrations end with a wall of text or a blob of HTML the model invented. Tambo takes a different route. You keep your existing React components and describe them to the agent; the agent's job is to choose one and fill in its props. The README puts it plainly: register your components with Zod schemas, and the agent picks the right one and streams the props so users can interact with them. The example given is "Show me sales by region" rendering your `<Chart>`, and "Add a task" updating your `<TaskBoard>`.
The audience is React teams that already own a design system and do not want a model generating markup they must sanitize, style-match, and keep accessible. If your components are the product surface, Tambo's premise is that the model should call them like functions rather than describe them in prose. That is a narrower bet than a general chat widget, and it is the whole point of the project.
How the mechanism works: Zod schemas become tool definitions, props stream into your tree
The README describes the loop in one line: Zod schemas define the props, and these schemas become LLM tool definitions. The agent calls them like functions and Tambo renders the result. So the schema is doing double duty: it is your runtime prop validation and the model's function signature.
Two component categories exist. Generative components render once in response to a message, which the README frames as charts, summaries, and data visualizations. Interactable components persist and update as users refine requests, with shopping carts, spreadsheets, and task boards as the stated examples. The distinction matters because it determines whether a component instance survives the next turn of the conversation.
On the client, `TamboProvider` wraps the app and receives the component registry. The README states you must provide either `userKey` or `userToken` to identify the thread owner, with `userKey` for server-side or trusted environments and `userToken` (an OAuth access token) for client-side apps where the token carries the user identity. `useTambo()` exposes messages and streaming state; `useTamboThreadInput()` handles input and submission. The backend, whether Tambo Cloud or self-hosted, owns conversation state and agent execution. Streaming, cancellation, error recovery, and reconnection are described as handled for you, which is the part most teams would otherwise write themselves.
Installing Tambo and registering your first component
The README's Get Started block is a scaffold command followed by a dev server. It notes that the scaffold auto-initializes git and runs tambo setup, so the project is wired before you touch it.
npm create tambo-app my-tambo-app # auto-initializes git + tambo setup
cd my-tambo-app
npm run devAfter that, the real work is the component registry. The README's generative component example declares a name, a description the agent reads, the component itself, and a Zod `propsSchema`:
const components: TamboComponent[] = [
{
name: "Graph",
description: "Displays data as charts using Recharts library",
component: Graph,
propsSchema: z.object({
data: z.array(z.object({ name: z.string(), value: z.number() })),
type: z.enum(["line", "bar", "pie"]),
}),
},
];For state that should survive follow-up messages, the README uses `withInteractable` instead, wrapping an existing component and giving it a `componentName`, a `description`, and a schema. The wrapped component is then rendered normally inside the provider, as in the README's `<InteractableNote id="note-1" ... />` line. The provider itself takes the API key, the user identity, and the component array:
<TamboProvider
apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}
userKey={currentUserId}
components={components}
>
<Chat />
<InteractableNote id="note-1" title="My Note" content="Start writing..." />
</TamboProvider>What you should see is your own component rendering with props the model chose, not a generated string. The README also points to a pre-built component library at ui.tambo.co and to two forkable templates, an AI chat with generative UI and an analytics dashboard.
Self-hosting Tambo: what docker-compose.yml actually stands up
The repository ships a `docker-compose.yml`, and reading it tells you what self-hosting costs in operational surface. Three services are defined. MinIO runs as S3-compatible storage on ports 9000 and 9001, with a console address on 9001 and a health check against `/minio/health/ready`. PostgreSQL 17 runs with a named volume and a health check using `pg_isready`. The web service builds from `apps/web/Dockerfile` and is published on host port 8260 mapped to container port 3000.
The environment wiring is the part to read carefully. The web service defaults `NEXT_PUBLIC_TAMBO_API_URL` to `http://localhost:8261`, which is a different port from the 8260 the web container publishes, so the API is expected to live elsewhere in the stack. Postgres is published on host port 5433 rather than 5432, presumably to avoid colliding with a local install. MinIO's root credentials default to `minioadmin` for both user and password, which is a development default and not something to expose.
There is a `docker.env.example` in the repository root and the compose file loads `./docker.env`, so configuration is expected to come from a file you create from that example. The README says self-hosted runs the same backend on your infrastructure via Docker, and that is the extent of what it documents here. There is no rollback procedure, no migration story, and no backup guidance in the README; if those matter to you, they are things you would have to work out from the compose file and the application's own behaviour.
Where Tambo is the wrong tool
The most obvious limit is the one the README states as a requirement: you must provide either `userKey` or `userToken`. There is no anonymous mode described. If your product has unauthenticated users, or if you cannot derive a stable identity at render time, the provider contract does not accommodate that as documented.
The second limit is the backend dependency. Tambo is described as a fullstack solution: a React SDK plus a backend that handles conversation state and agent execution. You either use Tambo Cloud or run the compose stack. That is a real constraint for a static site, an offline desktop build, or a team that has standardized on a different inference gateway and does not want a second service in the request path.
The third is React. The SDK is React-specific, with `TamboProvider`, `useTambo()`, and `useTamboThreadInput()`. If you are on Vue, Svelte, or a server-rendered stack without a React island, the component registry model does not transfer. And because the agent selects from the components you registered, coverage is bounded by your registry: a request that matches no registered component has nothing to render. The README does not describe a fallback path for that case, which is worth testing before you ship.
Tambo compared with a plain chat widget plus function calling
The nearest alternative is wiring an LLM tool-calling loop yourself: define tools, call them, and render the results with your own state management. That approach gives you full control over the transport, the provider, and the persistence layer, and it has no second service to operate. What it does not give you is the streaming-props machinery. The README claims cancellation, error recovery, and reconnection are handled, and those are exactly the pieces that are tedious to get right when props arrive incrementally and a user navigates away mid-stream.
A second alternative is a hosted component-generation product that emits markup the model writes from scratch. That inverts the trade-off: you get output for arbitrary requests, but you lose the guarantee that what renders is a component from your codebase with your styling and accessibility behaviour. Tambo's registry model is a deliberate restriction. If your product's value is a consistent, audited component set, the restriction is the feature. If your product's value is unbounded output, it is a wall.
The README also notes Tambo works with agent frameworks like LangChain and Mastra but they are not required, which positions it as a UI and streaming layer rather than a competing orchestration framework.
Licence, release cadence and upgrade cost
Tambo is MIT licensed, per the repository's LICENSE file and the licence badge in the README. MIT is permissive: you can use it commercially, modify it, and redistribute it, provided the copyright notice and permission notice are preserved. That is a statement about the licence text, not legal advice; if your organization has a review process for dependencies, run it.
The release history shows three independently versioned artifacts: `tambo-v0.56.2`, `web-v0.135.1`, and `showcase-v0.38.0`, all dated 2026-06-16. The version numbers are still in the 0.x range for the core package, and the web package is far ahead of it, which suggests the packages move at different rates. For a consumer of `@tambo-ai/react`, that means reading the changelog for the core package specifically rather than assuming a repository-wide version. The last push to the repository was on 2026-09-10, and the repository is not archived.
The upgrade cost is the usual one for a schema-driven SDK: your `propsSchema` definitions are the contract, and a change to how schemas are interpreted affects every registered component at once. The repository has a `RELEASING.md` and a `SELF-HOSTING.md` at the root, so both the release process and the self-hosting path are documented in-tree rather than only on the website. There is also a `TOKENS.md`, whose contents are not visible here, and a `stainless/` directory alongside `cli/`, `packages/`, `react-sdk/`, and `apps/`, indicating a monorepo with generated client code.
Editorial conclusion
Adopt Tambo if you already have a React component library and want an agent to select and populate those components rather than emit markup you have to sanitize. Skip it if you need framework-agnostic output, or if you cannot run a backend, because the SDK depends on a conversation service you either pay for through Tambo Cloud or operate yourself from docker-compose.yml. Before committing, verify three things: whether userKey or userToken matches your auth model, whether the self-hosted compose stack fits your infrastructure, and which LLM provider key you will bring. The README states that you must provide either userKey or userToken to identify the thread owner, and that constraint shapes the rest of your integration.
Frequently asked questions
What is Tambo AI?
It is an open-source React toolkit for generative UI, MIT licensed. You register your components with Zod schemas, and the agent selects a component and streams its props so users can interact with the rendered result.
How do I install Tambo in a React app?
The README's Get Started block uses the scaffold command npm create tambo-app my-tambo-app, which it says auto-initializes git and runs tambo setup, followed by cd my-tambo-app and npm run dev.
Does Tambo need its own backend?
Yes. The README describes Tambo as a fullstack solution: a React SDK plus a backend that handles conversation state and agent execution. That backend is either Tambo Cloud or the self-hosted compose stack in the repository.
Can I self-host Tambo?
The README says self-hosted runs the same backend on your infrastructure via Docker. The repository includes a docker-compose.yml with MinIO, PostgreSQL 17, and a web service built from apps/web/Dockerfile, plus a docker.env.example to copy configuration from.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tambo-ai-tambo)