npx claudepluginhub tambo-ai/tambo --plugin tamboThis skill uses the workspace's default tool permissions.
Detect tech stack and integrate Tambo while preserving existing patterns.
Scaffolds new Tambo generative UI React apps from scratch via tambo create-app CLI. Gathers app type, Next.js or Vite framework, and name; sets up TamboProvider and starter components.
Convert designs to React/Next.js components with TailwindCSS, TypeScript, and typed API hooks. Use when scaffolding frontend from designs.
Provides shadcn/ui patterns for CLI-based installation, configuration, theme customization with Tailwind CSS, registry workflows, and implementation of accessible components like buttons, dialogs, tables, forms with React Hook Form and Zod.
Share bugs, ideas, or general feedback.
Detect tech stack and integrate Tambo while preserving existing patterns.
Load these when you reach the relevant step or need deeper implementation details:
tambo add component library, tambo init flags, non-interactive mode.Shared references (components, rendering, threads, tools/context, CLI) are duplicated into generative-ui so each skill works independently. add-components-to-registry is unique to this skill.
Check these files to understand the project:
# Key files to read
package.json # Dependencies, scripts, AND package manager
tsconfig.json # TypeScript config, path aliases
next.config.* # Next.js
vite.config.* # Vite
tailwind.config.* # Tailwind CSS
postcss.config.* # PostCSS
src/index.* or app/ # Entry points
yarn.lock / pnpm-lock.yaml / package-lock.json # Which package manager
| Technology | Detection |
|---|---|
| Next.js | next in dependencies, next.config.* exists |
| Vite | vite in devDependencies, vite.config.* exists |
| Create React App | react-scripts in dependencies |
| TypeScript | typescript in deps, tsconfig.json exists |
| Tailwind | tailwindcss in deps, config file exists |
| Plain CSS | No Tailwind, CSS files in src/ |
| Zod | zod in dependencies |
| Other validation | yup, joi, superstruct in deps |
Always detect and use the project's package manager. Do not assume npm.
| Lock file | Manager | Install command |
|---|---|---|
package-lock.json | npm | npm install @tambo-ai/react |
yarn.lock | Yarn | yarn add @tambo-ai/react |
pnpm-lock.yaml | pnpm | pnpm add @tambo-ai/react |
For monorepos, install in the correct workspace:
yarn workspace <app-name> add @tambo-ai/reactpnpm --filter <app-name> add @tambo-ai/reactnpm install @tambo-ai/react -w <app-name>Check for monorepo indicators:
workspaces field in root package.jsonpnpm-workspace.yamlturbo.json or nx.jsonpackage.json files in apps/ or packages/If monorepo detected, identify which package is the web app that will use Tambo (usually in apps/web, apps/frontend, or similar).
Check if the app captures keyboard events globally (common in drawing tools, editors, IDEs). Look for:
document.addEventListener("keydown", ...) in the codebaseIf found, the Tambo chat UI wrapper must stop event propagation (see Step 6).
Present findings including the package manager and any special concerns:
I detected your project uses:
- Framework: Next.js 14 (App Router)
- Package manager: Yarn
- Styling: Tailwind CSS
- Validation: No Zod (will need to add)
- TypeScript: Yes
- Monorepo: No
- Global keyboard shortcuts: No
Should I:
1. Install Tambo with these settings?
2. Use plain CSS instead of Tailwind for Tambo components?
3. Something else?
Use the project's package manager (detected in Step 1):
# npm
npm install @tambo-ai/react
npm install zod # if no Zod installed
# yarn
yarn add @tambo-ai/react
yarn add zod
# pnpm
pnpm add @tambo-ai/react
pnpm add zod
# Monorepo (install in the correct workspace)
yarn workspace <app-name> add @tambo-ai/react zod
pnpm --filter <app-name> add @tambo-ai/react zod
npm install @tambo-ai/react zod -w <app-name>
// app/providers.tsx
"use client";
import { TamboProvider } from "@tambo-ai/react";
import { components } from "@/lib/tambo";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<TamboProvider
apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY}
userKey="default-user"
components={components}
>
{children}
</TamboProvider>
);
}
IMPORTANT: userKey is required for authentication. Without it, message submission fails at runtime with "authentication is not ready." Note: userKey is typed as optional in TypeScript (userKey?: string), so the compiler won't catch this — the failure is purely at runtime. In production, use a real user identifier (e.g., session ID, user ID from your auth system). For development/demo, a static string such as "default-user" works.
// app/layout.tsx
import { Providers } from "./providers";
export default function RootLayout({ children }) {
return (
<html>
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}
// pages/_app.tsx
import { TamboProvider } from "@tambo-ai/react";
import { components } from "@/lib/tambo";
export default function App({ Component, pageProps }) {
return (
<TamboProvider
apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY}
userKey="default-user"
components={components}
>
<Component {...pageProps} />
</TamboProvider>
);
}
// src/main.tsx
import { TamboProvider } from "@tambo-ai/react";
import { components } from "./lib/tambo";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root")!).render(
<TamboProvider
apiKey={import.meta.env.VITE_TAMBO_API_KEY}
userKey="default-user"
components={components}
>
<App />
</TamboProvider>,
);
// lib/tambo.ts (or src/lib/tambo.ts)
import { TamboComponent } from "@tambo-ai/react";
export const components: TamboComponent[] = [
// Components will be registered here
];
Pick the right chat layout for the app:
| Component | Best for | How it renders |
|---|---|---|
message-thread-collapsible | Overlaying on top of existing UI (drawing tools, simple apps) | Fixed-position floating panel, bottom-right corner, toggle open/close |
message-thread-panel | Apps with sidebar layouts (dashboards, admin panels, SaaS apps) | Side panel with thread history, resizable |
message-thread-full | Dedicated chat pages or full-screen chat experiences | Full-height thread with all features |
Choose based on the app's layout. If there's a sidebar or dashboard layout, use panel. If the chat should float over existing content, use collapsible. If the whole page is the chat, use full.
npx tambo add message-thread-panel --yes
# Or: npx tambo add message-thread-collapsible --yes
# Or: npx tambo add message-thread-full --yes
# With other package managers:
# yarn dlx tambo add <component> --yes
# pnpm dlx tambo add <component> --yes
tambo add, complete the setup:CSS setup — tambo add adds Tailwind directives and CSS variables to your project's CSS entry file. The file it modifies depends on the framework:
app/globals.css (or src/app/globals.css) — already imported in layout by default.src/index.css (or index.css) — already imported in main.tsx by default.If your entry file already imports a CSS file, tambo add modifies that file in place. No new import is needed.
Path alias — Tambo components use @/ imports. Check if the project's tsconfig already has @/* in its paths. Many Next.js projects created with create-next-app have this, but not all (e.g., Cal.com uses ~/* and @components/* instead).
If @/* is missing, add it to the app tsconfig (tsconfig.app.json when present, otherwise tsconfig.json):
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}
If the project has no src/ directory and components land in the project root, use ["./*"] instead of ["./src/*"]. Check where tambo add placed the components to determine the correct path.
For Vite projects, also add the alias to vite.config.ts:
// vite.config.ts
import path from "path";
export default defineConfig({
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
},
},
});
Critical for apps with global keyboard shortcuts (drawing tools, editors, terminal-like apps). Without this, typing in the Tambo chat input triggers the host app's shortcuts.
Wrap the Tambo chat UI in a div that stops keyboard event propagation:
<div
onKeyDown={(e) => e.stopPropagation()}
onKeyUp={(e) => e.stopPropagation()}
>
{/* Use whichever component you installed */}
<MessageThreadCollapsible />{" "}
{/* or <MessageThreadPanel /> or <MessageThreadFull /> */}
</div>
Apps with full-screen canvases or overlays may render on top of the Tambo chat. The MessageThreadCollapsible component uses position: fixed, but the host app's canvas may have a higher stacking context. Wrap with a fixed container that sits above everything:
<div
style={{ position: "fixed", inset: 0, zIndex: 9999, pointerEvents: "none" }}
>
<div style={{ pointerEvents: "auto" }}>
{/* Use whichever component you installed */}
<MessageThreadCollapsible />{" "}
{/* or <MessageThreadPanel /> or <MessageThreadFull /> */}
</div>
</div>
The outer div creates a stacking context above the canvas, while pointerEvents: none/auto ensures only the chat panel is clickable — the rest of the screen passes clicks through to the canvas.
You can combine keyboard isolation and z-index in one wrapper.
If the project doesn't use Tailwind, tambo add will install Tailwind v4 via PostCSS alongside the existing styling. This is additive — it won't break existing CSS/SCSS. The Tambo components use Tailwind, but the rest of your app keeps its styling.
If you'd prefer to avoid Tailwind entirely:
# Skip --yes flag to customize styling during add
npx tambo add message-thread-full
# Select "CSS Modules" or "Plain CSS" when prompted
If using Yup/Joi instead of Zod, user can either:
Run commands from the web app package, not the monorepo root.
Run npx tambo init --project-name=<app-name> from the web app directory. This opens the browser for authentication and polls until the user completes auth (up to 15 minutes). Use a long timeout. Once auth completes, the CLI creates the project and writes the API key to .env.local.
Monorepo gotchas:
tambo init creates .env.local in the current directory. Vite loads env from envDir (check vite.config.*). Ensure the env file is where Vite looks for it.yarn add -W @tambo-ai/react).vite.config.* directory. The @/ alias must resolve to the correct src/ directory within the workspace, not the monorepo root.npx tambo init --project-name=<name> opens the browser and polls until the user authenticates (up to 15 minutes). Use a long timeout. Once auth completes, it creates the project and writes .env.local.
If manual setup is needed (monorepo, read-only filesystem), add the appropriate variable:
| Framework | Variable |
|---|---|
| Next.js | NEXT_PUBLIC_TAMBO_API_KEY |
| Vite | VITE_TAMBO_API_KEY |
| CRA | REACT_APP_TAMBO_API_KEY |
After setup, verify by creating a simple test:
import { useTambo } from "@tambo-ai/react";
function TestComponent() {
const { thread, isIdle } = useTambo();
console.log("Tambo connected:", isIdle);
return <div>Tambo is set up!</div>;
}
If you encounter any of these while helping a user, suggest filing a GitHub issue:
@tambo-ai/react, @tambo-ai/client, or the tambo CLIUse this template when drafting an issue for tambo-ai/tambo:
**Title:** [Short description of the problem]
**Expected behavior**
What should happen.
**Actual behavior**
What happens instead, including any error messages or stack traces.
**Repro steps**
1. Run `npx tambo create-app ...` (or whatever command)
2. Add this code:
```tsx
// minimal code that reproduces the issue
```
3. Observe the error
**Environment**
- `@tambo-ai/react` version:
- `@tambo-ai/client` version:
- Framework (Next.js / Vite / CRA) and version:
- Node.js version:
- OS:
**Additional context**
Link to relevant docs or skill file path if applicable.
Security: Redact API keys, tokens, and any customer data before including logs or code snippets in the issue.
When you hit a problem that looks like a Tambo bug, say something like:
This looks like a bug in
@tambo-ai/react. Want me to open a GitHub issue ontambo-ai/tambowith the repro steps and environment details?
Always wait for the user to confirm before filing.