Get assistant-ui running in 5 minutes with npm and your first chat component.
Quick Start
The fastest way to get started with assistant-ui.

Initialize assistant-ui
Create a new project:
npx assistant-ui@latest createOr start from a template:
npx assistant-ui@latest create -t cloudThe CLI reference lists every template and example, and what each one includes.
Add to an existing project:
npx assistant-ui@latest initAdd API key
Create a .env file with your API key:
OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Developing locally with a ChatGPT Plus or Pro plan? You can skip the API key and run on your subscription instead; see ChatGPT Subscription.
Start the app
npm run devManual Setup
If you prefer not to use the CLI, you can install components manually.
Add the assistant-ui registry to your components.json so the shadcn CLI resolves components for your style. Styles whose name starts with base- receive Base UI flavored components; all other styles receive the Radix flavored ones. npx shadcn init defaults to Base UI styles (for example base-nova), so new projects need this style-aware URL for components that compile against that stack.
{
"registries": {
"@assistant-ui": "https://r.assistant-ui.com/styles/{style}/{name}.json"
}
}Existing Radix projects can keep the plain form https://r.assistant-ui.com/{name}.json as a fallback (for example npx shadcn@latest add https://r.assistant-ui.com/thread.json).
Add assistant-ui
npx shadcn@latest add @assistant-ui/thread @assistant-ui/thread-listThe @assistant-ui namespace resolves the Radix or Base UI flavor from your project's style through the style-aware registry entry in components.json. Without that entry, add by direct URL instead:
npx shadcn@latest add https://r.assistant-ui.com/base/thread.json https://r.assistant-ui.com/base/thread-list.jsonPrerequisites
- Setup React
- Setup shadcn/ui
Follow the manual installation guide to configure:
- Tailwind CSS
- TypeScript path aliases
- tw-animate-css
- The cn helper
- components.json (for CLI usage)
Main Component
npm install @assistant-ui/reactassistant-ui dependencies
npm install @assistant-ui/react @assistant-ui/react-markdown class-variance-authority remark-gfm tw-shimmer zustandshadcn/ui dependencies
npm install @base-ui/reactSetup Backend Endpoint
Install provider SDK:
npm install ai @assistant-ui/ai-sdk @ai-sdk/openainpm install ai @assistant-ui/ai-sdk @ai-sdk/anthropicnpm install ai @assistant-ui/ai-sdk @ai-sdk/azurenpm install ai @assistant-ui/ai-sdk @ai-sdk/amazon-bedrocknpm install ai @assistant-ui/ai-sdk @ai-sdk/googlenpm install ai @assistant-ui/ai-sdk @ai-sdk/google-vertexnpm install ai @assistant-ui/ai-sdk @ai-sdk/groqnpm install ai @assistant-ui/ai-sdk @ai-sdk/fireworksnpm install ai @assistant-ui/ai-sdk @ai-sdk/coherenpm install ai @assistant-ui/ai-sdk ollama-ai-provider-v2npm install ai @assistant-ui/ai-sdk chrome-aiAdd an API endpoint:
import { openai } from "@ai-sdk/openai";
import { frontendTools } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, streamText } from "ai";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages, system, tools } = await req.json();
const result = streamText({
model: openai("gpt-5.6-luna"),
system,
messages: await convertToModelMessages(messages),
tools: frontendTools(tools),
});
return result.toUIMessageStreamResponse();
}import { anthropic } from "@ai-sdk/anthropic";
import { frontendTools } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, streamText } from "ai";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages, system, tools } = await req.json();
const result = streamText({
model: anthropic("claude-sonnet-4-6"),
system,
messages: await convertToModelMessages(messages),
tools: frontendTools(tools),
});
return result.toUIMessageStreamResponse();
}import { azure } from "@ai-sdk/azure";
import { frontendTools } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, streamText } from "ai";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages, system, tools } = await req.json();
const result = streamText({
model: azure("your-deployment-name"),
system,
messages: await convertToModelMessages(messages),
tools: frontendTools(tools),
});
return result.toUIMessageStreamResponse();
}import { bedrock } from "@ai-sdk/amazon-bedrock";
import { frontendTools } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, streamText } from "ai";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages, system, tools } = await req.json();
const result = streamText({
model: bedrock("anthropic.claude-sonnet-4-6-v1:0"),
system,
messages: await convertToModelMessages(messages),
tools: frontendTools(tools),
});
return result.toUIMessageStreamResponse();
}import { google } from "@ai-sdk/google";
import { frontendTools } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, streamText } from "ai";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages, system, tools } = await req.json();
const result = streamText({
model: google("gemini-2.0-flash"),
system,
messages: await convertToModelMessages(messages),
tools: frontendTools(tools),
});
return result.toUIMessageStreamResponse();
}import { vertex } from "@ai-sdk/google-vertex";
import { frontendTools } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, streamText } from "ai";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages, system, tools } = await req.json();
const result = streamText({
model: vertex("gemini-2.0-flash"),
system,
messages: await convertToModelMessages(messages),
tools: frontendTools(tools),
});
return result.toUIMessageStreamResponse();
}import { groq } from "@ai-sdk/groq";
import { frontendTools } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, streamText } from "ai";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages, system, tools } = await req.json();
const result = streamText({
model: groq("llama-3.3-70b-versatile"),
system,
messages: await convertToModelMessages(messages),
tools: frontendTools(tools),
});
return result.toUIMessageStreamResponse();
}import { fireworks } from "@ai-sdk/fireworks";
import { frontendTools } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, streamText } from "ai";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages, system, tools } = await req.json();
const result = streamText({
model: fireworks("accounts/fireworks/models/llama-v3p3-70b-instruct"),
system,
messages: await convertToModelMessages(messages),
tools: frontendTools(tools),
});
return result.toUIMessageStreamResponse();
}import { cohere } from "@ai-sdk/cohere";
import { frontendTools } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, streamText } from "ai";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages, system, tools } = await req.json();
const result = streamText({
model: cohere("command-r-plus"),
system,
messages: await convertToModelMessages(messages),
tools: frontendTools(tools),
});
return result.toUIMessageStreamResponse();
}import { ollama } from "ollama-ai-provider-v2";
import { frontendTools } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, streamText } from "ai";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages, system, tools } = await req.json();
const result = streamText({
model: ollama("llama3"),
system,
messages: await convertToModelMessages(messages),
tools: frontendTools(tools),
});
return result.toUIMessageStreamResponse();
}import { chromeai } from "chrome-ai";
import { frontendTools } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, streamText } from "ai";
export const maxDuration = 30;
export async function POST(req: Request) {
const { messages, system, tools } = await req.json();
const result = streamText({
model: chromeai(),
system,
messages: await convertToModelMessages(messages),
tools: frontendTools(tools),
});
return result.toUIMessageStreamResponse();
}Define environment variables:
OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"ANTHROPIC_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"AZURE_RESOURCE_NAME="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
AZURE_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"AWS_ACCESS_KEY_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
AWS_SECRET_ACCESS_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
AWS_REGION="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"GOOGLE_GENERATIVE_AI_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"GOOGLE_VERTEX_PROJECT="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
GOOGLE_VERTEX_LOCATION="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
GOOGLE_APPLICATION_CREDENTIALS="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"GROQ_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"FIREWORKS_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"COHERE_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"<none><none>If you aren't using Next.js, you can also deploy this endpoint to Cloudflare Workers, or any other serverless platform.
Use it in your app
import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/ai-sdk";
import { ThreadList } from "@/components/assistant-ui/elements/thread-list.aui";
import { Thread } from "@/components/assistant-ui/elements/thread.aui";
export default function MyApp() {
const runtime = useChatRuntime({
transport: new AssistantChatTransport({
api: "/api/chat",
}),
});
return (
<AssistantRuntimeProvider runtime={runtime}>
<div>
<ThreadList />
<Thread />
</div>
</AssistantRuntimeProvider>
);
}// run `npx shadcn@latest add @assistant-ui/assistant-modal`
import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/ai-sdk";
import { AssistantModal } from "@/components/assistant-ui/elements/assistant-modal.aui";
export default function MyApp() {
const runtime = useChatRuntime({
transport: new AssistantChatTransport({
api: "/api/chat",
}),
});
return (
<AssistantRuntimeProvider runtime={runtime}>
<AssistantModal />
</AssistantRuntimeProvider>
);
}