CopilotKit and Vercel AI SDK alternatives: what you still build
Compare CopilotKit, assistant-ui, ChatKit, the Vercel AI SDK and Teaflask by layer: what each ships, what you still build, and who should choose which.
If you are comparing CopilotKit and Vercel AI SDK alternatives, start with what each option already supplies: chat components, basic attachments and approval controls vary by library. The backend, durable storage and enforcement of approval decisions are separate choices. A platform such as Teaflask hosts the runtime, history and file storage; libraries let you assemble more of the stack yourself.
The matrix below checks five options, CopilotKit, assistant-ui, OpenAI ChatKit, the Vercel AI SDK and Teaflask, against each vendor's own documentation as of October 2026.
Each option covers a different stretch of the stack, so start with the layers.
What are the layers of an embedded assistant UI?
An embedded assistant UI has seven layers: the chat components, an agent runtime, thread persistence, attachment storage, an approval interface, support for your frontend framework, and style isolation. Most component libraries cover the first well and offer the rest as hooks, adapters or hosted add-ons. A demo shows you the first layer. The other six turn up once real users start closing tabs, attaching PDFs and asking who approved that.
| Layer | What it is |
|---|---|
| Chat components | The visible interface: the composer (the message box), the transcript, send and stop. |
| Agent runtime and backend | The server loop that calls the model, runs tools, streams the reply and records each turn. A turn is the agent's work on one user message. |
| Thread persistence | Stored conversations that survive a reload and appear in a history list. |
| Attachment upload and storage | Picking a file, sending it somewhere durable and showing it again in the transcript. |
| Approval UI | The interface that asks a person to approve or deny an action. The runtime must enforce the decision before execution. Also called human-in-the-loop. |
| Non-React support | Whether the interface works in Vue, Svelte, Angular or a server-rendered stack. |
| Style isolation | Whether your page's CSS can reach the assistant, and how you restyle it to match your product. |
Which layers does each option include?
Four of the five options leave the agent runtime and thread storage to you, or to a hosted add-on. Teaflask hosts both, at the cost of a more opinionated interface. Read each cell as who supplies the layer, then read the note for the catch. The four others are alphabetical and Teaflask, which we make, sits last. This is a layer-by-layer comparison, not a ranking.
Chat components
| Option | Provision | Details |
|---|---|---|
| assistant-ui | Included | Shadcn-style components copied into your repo, built on unstyled primitives. |
| CopilotKit | Included | CopilotChat, CopilotSidebar and CopilotPopup, themable with CSS variables and slots. |
| OpenAI ChatKit | Included | A chat embed with widgets, tool-invocation support and attachments, loaded from an OpenAI script. |
| Vercel AI SDK UI | You build | Hooks only. AI Elements adds optional components; its site announces a move to shadcn/ui and deprecation at the end of Nov 2026. |
| Teaflask (ours) | Included | Composer, transcript, approval cards and four surfaces, from one React component or a script tag. |
Agent runtime and backend
| Option | Provision | Details |
|---|---|---|
| assistant-ui | You build | Bring your own: the AI SDK, LangGraph or a custom backend. |
| CopilotKit | You build | You host a CopilotKit runtime and the agent it connects to. |
| OpenAI ChatKit | You build | Your own server on the ChatKit Python SDK. The hosted Agent Builder path shuts down 30 Nov 2026. |
| Vercel AI SDK UI | You build | Your API route calls the model; the hooks consume the stream. |
| Teaflask (ours) | Included | Hosted runtime. A turn keeps going after the tab closes. |
Thread persistence
| Option | Provision | Details |
|---|---|---|
| assistant-ui | Hosted add-on | Assistant Cloud stores threads, or connect your own persistence. With no thread configuration, one in-memory thread resets on reload. |
| CopilotKit | Hosted add-on | CopilotKit Intelligence, cloud or self-hosted. The Threads Drawer needs it. |
| OpenAI ChatKit | You build | Implement a Store for threads and messages in your own database. |
| Vercel AI SDK UI | You build | You write saveChat and loadChat. Resuming streams needs storage you set up. |
| Teaflask (ours) | Included | Every conversation is kept. Identified users get up to 200 in a history menu. |
Attachments
| Option | Provision | Details |
|---|---|---|
| assistant-ui | Included / storage you supply | useChatRuntime includes a data-URL adapter. Other runtimes may need one. Durable uploads need Assistant Cloud or your own storage adapter. |
| CopilotKit | Included / storage you supply | Enable basic attachments in CopilotChat: base64 inline by default, or your own onUpload. Intelligence is separate from basic file input. |
| OpenAI ChatKit | You build | Off by default. Provide a FileStore for direct or two-phase uploads. |
| Vercel AI SDK UI | You build | useChat sends files, as data URLs for images and text. Storage is not covered in the docs we read. |
| Teaflask (ours) | Included | A per-agent setting. Up to 10 files per message, uploaded from the browser to storage. |
Approval UI
| Option | Provision | Details |
|---|---|---|
| assistant-ui | Included basic controls | Default ToolFallback includes approval buttons and a decision receipt. Wire a compatible runtime/server approval gate; a custom renderer is optional. |
| CopilotKit | You build | useHumanInTheLoop and useInterrupt pause a turn and render your component. |
| OpenAI ChatKit | You build | Widgets and client tools are the parts. We found no prebuilt approval card. |
| Vercel AI SDK UI | You build | A tool part reaches approval-requested and you call addToolApprovalResponse. |
| Teaflask (ours) | Included | Approval and question cards. Allow, Ask or Deny is set per action on the server. |
Non-React frontends
| Option | Provision | Details |
|---|---|---|
| assistant-ui | Partial | React, plus Vue and React Native in separate packages. |
| CopilotKit | Partial | React first. Its docs also cover Angular. |
| OpenAI ChatKit | Partial | A web component with a React binding. We did not check Vue or server-rendered guides. |
| Vercel AI SDK UI | Partial | Bindings for React, Vue, Svelte and Angular. API names differ by framework; you still draw the interface. |
| Teaflask (ours) | Included | A script tag works in Vue, Svelte, Angular, Rails, Django, Laravel and WordPress. |
Style isolation
| Option | Provision | Details |
|---|---|---|
| assistant-ui | Your CSS | Component source lives in your repo, so you style it like your own code. |
| CopilotKit | Themable | Chat theming uses CSS variables, class overrides and slots. The Threads Drawer uses a shadow root with self-contained styles; that does not establish isolation for every chat surface. |
| OpenAI ChatKit | Themable | Colour scheme, accent, radius, density and font. The docs we read do not describe host-CSS isolation. |
| Vercel AI SDK UI | You build | No interface of its own. AI Elements follows shadcn/ui conventions, so your theme applies. |
| Teaflask (ours) | Shadow root | Script tag: your selectors cannot reach it. The npm package renders in your page. Theme with --tf-* tokens. |
What is each option great at, and what do you still own?
Past the interface, each option leaves you a different list. assistant-ui leaves the backend and a persistence strategy: Assistant Cloud or your own thread and upload storage. CopilotKit leaves the runtime and the agent. ChatKit leaves a server with its own Store and FileStore. The Vercel AI SDK leaves nearly everything. Teaflask leaves an actions adapter and the choice of which actions to grant.
The entries run alphabetically, with Teaflask in its own slot at the end. One naming note: assistant-ui, written with a hyphen, is an unrelated open-source library, not Teaflask's Assistant UI.
assistant-ui
Open-source React library
Components you own. The CLI copies shadcn-style component source into your repo, so restyling means editing files your team already reviews. It builds on unstyled primitives, accepts the backend you have (the AI SDK, LangGraph or your own), and has separate Vue and React Native packages.
What you still own. The backend, which you bring. With no thread configuration the runtime renders one thread that resets on reload. useChatRuntime includes a default attachment adapter that converts files to base64 data URLs; other runtimes, such as useLocalRuntime, need an adapter for uploads. Durable file storage needs Assistant Cloud or your own upload adapter, such as one using presigned URLs. The default ToolFallback already renders approval controls and a decision receipt for unregistered tools. A custom renderer is optional, but you still wire the compatible runtime or server gate that pauses execution and consumes the decision.
CopilotKit
Toolkit: components, hooks, runtime you host
Drop-in chat surfaces on an open protocol. CopilotChat, CopilotSidebar and CopilotPopup cover inline, docked and floating layouts, and all three can be themed with CSS variables, class overrides or slots. It is mostly a toolkit: open-source UI components and hooks plus a runtime you host, with agents built in frameworks such as LangGraph, Google ADK or Mastra.
What you still own. The runtime and the agent behind it. Threads, the Threads Drawer and the useThreads hook depend on CopilotKit Intelligence, which runs on CopilotKit Cloud or on your own infrastructure with PostgreSQL and Redis; a self-hosted drawer without a license shows a locked view. Basic attachments do not require Intelligence: enable them on CopilotChat for file selection, previews and inline multimodal input. Files travel as base64 unless you supply an onUpload that returns a URL from your storage. Persisted thread replay is a separate layer. Approvals use useHumanInTheLoop or useInterrupt and render whatever component you write.
OpenAI ChatKit
Chat embed plus a server SDK
A finished chat embed from the model vendor. It handles the interface details, including widgets, tool-invocation support, file attachments and chain-of-thought views, and it themes by colour scheme, accent, radius, density and font.
What you still own. A server. For new work, OpenAI's docs point to a custom integration on your own infrastructure: you use the ChatKit Python SDK and implement a Store for threads, messages and files and a FileStore for uploads. Attachments are off until you configure them. The Agent Builder-hosted path is deprecated, with shutdown scheduled for 30 Nov 2026, while ChatKit itself stays available.
Vercel AI SDK UI
Hooks
Bindings that stay out of your design. React and Vue expose useChat, useCompletion and useObject; Svelte and Angular use Chat, Completion and StructuredObject. They manage stream and message state, and the interface is whatever you compose.
What you still own. Everything visible. AI Elements offers optional components built on shadcn/ui, though its own site says the project is moving to shadcn/ui and will be deprecated at the end of November 2026. Persistence is functions you write: the docs' example stores chats in files and says a real application would use a database, and resuming a stream needs storage you set up. useChat can send files, but the persistence page does not address where attachments live. Approval means reading the approval-requested tool state and calling addToolApprovalResponse.
Teaflask
Hosted platform (the product we make)
Everything above the model call is hosted. The runtime, the conversation history and the file storage run on Teaflask, and one React component or script tag mounts a composer with attachments, a streaming transcript, approval cards and four surfaces: corner widget, drawer, command palette and full page. The script tag works outside React. The Teaflask Assistant UI guide covers each part.
What you still own. The actions adapter, a small piece of frontend code that sends the agent's requests to your API with the signed-in user's session. You also decide which actions to grant, and you create a publishable key listing the origins that may use it. Beyond that, you take Teaflask's runtime and interface as they come instead of assembling your own, which costs some freedom; the limits are listed further down.
Who should choose a component library, and who a pre-built platform?
Choose a component library when you want a custom interface, already run an agent backend, or want the UI source in your own repo. Choose a pre-built platform when you want threads, attachments and approvals working without running that infrastructure, or when your stack is not React. A quick test for any layer in the matrix: name the person who gets paged when it breaks.
A component library fits when
You want to own the experience and have engineers who enjoy that work.
- You need an interface that looks like nothing else, down to the layout of the composer.
- You already run an agent backend and only the frontend is missing.
- Your team is React-only and wants the component source in its own repo.
- Policy keeps the runtime and conversation data inside your own infrastructure.
- The assistant is the product you sell, so every layer is yours to shape.
A pre-built platform fits when
The assistant is a feature you need, and the stack behind it would be new to run.
- You want threads, attachments and approvals without operating a runtime, a database and file storage.
- Your frontend is Vue, Svelte, Angular or server-rendered, not React.
- Nobody on the team wants to own an agent backend.
- You would rather customize through tokens and tool views than through component source.
Where is Teaflask weaker?
Teaflask is weaker in four places: the interface is opinionated, a custom interface cannot upload files, there is no tested list of minimum browser versions, and anonymous visitors get no history list. Each one can rule it out for the right team.
- An opinionated interface
- You choose among four surfaces and restyle them with tokens, dark mode and your own tool views. Changing the layout of the composer or the transcript itself means going headless, which is npm only.
- A custom interface sends text only
- The headless hooks have no upload helper, so an interface you build by hand cannot attach files. Attachments exist only in the built-in surfaces.
- No tested browser list
- Teaflask publishes no tested minimum versions. It needs streaming fetch plus the native dialog and popover APIs, and the script tag also needs custom elements and Shadow DOM, so check the browsers and WebViews you support.
- Anonymous visitors get no history list
- A signed-out visitor resumes the open conversation on reload but has no history menu. History across devices needs an identified user.
Questions buyers ask before choosing
Which CopilotKit and Vercel AI SDK alternatives come with a ready-to-ship UI?
Of the options compared here, OpenAI ChatKit, CopilotKit and Teaflask ship finished chat interfaces, and assistant-ui ships components you copy into your repo. The Vercel AI SDK ships hooks and leaves the interface to you. What sits behind the interface differs more than the interface does: ChatKit and CopilotKit both expect you to run a server, while Teaflask hosts the runtime, history and file storage.
Does CopilotKit include threads?
Yes, through CopilotKit Intelligence rather than through the open-source runtime alone. A runtime with no persistence layer keeps nothing server-side, and the Threads Drawer and the useThreads hook depend on Intelligence, cloud-hosted or self-hosted. Its docs also describe keeping your own thread storage while Intelligence records a separate copy. The free hosted tier has limits listed on CopilotKit's pricing page.
Does assistant-ui handle attachments?
Yes. useChatRuntime includes a default adapter that converts files to base64 data URLs, with no extra runtime configuration. You still include the attachment UI components. Other runtimes, such as useLocalRuntime, need an adapter for file uploads. For durable uploads and large files, use Assistant Cloud or your own storage adapter, such as the documented presigned-URL pattern. Check that your model supports the file types you accept.
Does assistant-ui include approval buttons?
Yes. Thread uses ToolFallback by default for tools without a dedicated renderer. It shows approval controls while a decision is required, then a receipt. Depending on the tool-call state, it uses addResult, resume or respondToApproval. A custom renderer is optional; the runtime or server must still pause execution and enforce the user's decision.
Do CopilotKit attachments require Intelligence?
No. Enable attachments on CopilotChat for file selection, previews and multimodal message input. Files are sent inline as base64 by default, or your onUpload handler can upload to your storage and return a URL. Intelligence-based thread persistence and replay are separate from basic attachments; model support still determines which file types the agent can use.
Can I use a pre-built UI with Vue or Rails?
Yes, if the UI ships as a web component. Teaflask's script tag loads the same assistant into Vue, Svelte, Angular, Rails, Django, Laravel or WordPress, inside a shadow root. OpenAI ChatKit also loads from a script, though we did not check its guides for those stacks. The libraries mostly target React, with Vue packages for assistant-ui and the AI SDK and Angular coverage in CopilotKit's docs.
Where to go next
The full Teaflask guide covers the composer, threads, attachments and every surface, and the install docs get the assistant onto your pages.
- Teaflask Assistant UI guide
The composer, threads, attachments, surfaces, theming and the built-in limits.
- Install the assistant
One React component or one script tag, step by step.
- Embedded AI assistants: a buyer's guide
What embedded assistants are, the five kinds on the market, and eight questions to put to every vendor.