Every one of these four gets you a streaming message list in an afternoon, which is why the evaluations all end in a tie and the decision gets made on taste. The thing you are actually choosing is the layer you cannot swap out in month nine — a wire protocol, an npm dependency, a source tree copied into your repo, or an entire Python server whose front end you never wrote. After a year in which one visual builder archived itself and another changed owners, that layer deserves the whole decision.
At a glance
Four projects, four different answers to "what did I just take a dependency on".
| Project | Shape | What you install | What you own if it goes quiet |
|---|---|---|---|
| CopilotKit | React frontend plus a runtime, speaking the AG-UI protocol | Packages, a runtime endpoint, a protocol | The protocol and your agent; the runtime is the fork |
| assistant-ui | Headless React primitives over your own transport | An npm dependency, shadcn/ui-shaped components | Your transport and your styling; the primitives are the fork |
| AI Elements | Components copied into your repo, welded to the AI SDK stream | Source files in your tree, plus the AI SDK | The components outright; the stream protocol is the lock |
| Chainlit | A Python server that renders its own front end | An application you configure rather than compose | Your Python handlers; the UI was never yours |
Four couplings, one message list
Chat UI arguments usually get conducted over component quality: does it do message branching, attachments, markdown, tool-call rendering. By 2026 they all do, and the differences are a week of work either way. The durable difference is which layer the project claims.
CopilotKit claims the wire. It is MIT-licensed, raised $27M in May 2026, and its centre of gravity is AG-UI — an open agent-to-user protocol that emerged from a partnership with LangChain, with CrewAI joining shortly after. What you get for the weight is bidirectional state: the agent can read and update application state, propose an interrupt that the user answers, and stream structured events rather than tokens. If your agent needs to know what the user has selected in your app, that is the product. If it does not, you are running a protocol and a runtime to render a message list.
assistant-ui claims the components, and deliberately not the wire. MIT, React, built on shadcn/ui and Tailwind conventions, and happy to sit on top of the AI SDK's useChat or on your own route handler. Thread persistence, analytics and similar are an optional hosted service rather than a requirement. It is the choice that assumes you already have a backend you like and want the chat surface to be the least opinionated part of the stack.
AI Elements claims the components too, but hands you the source. It is a shadcn-style registry: you run a command and the component files land in your repository, more than twenty of them, already wired to the AI SDK's streaming primitives — the message-parts model that arrived with AI SDK 6. There is no upgrade path because there is no dependency to upgrade, which is either the best or the worst property in this table depending on how you feel about owning code you did not write.
Chainlit claims everything above your handlers. Python, Apache-2.0, and the fastest route from a script to something you can send a colleague: a polished web UI with reasoning steps, file uploads and markdown, from a decorated Python function. The front end is the product's, not yours, and diverging from it means leaving.
Copy-in versus depend-on: the split that shows up in month six
assistant-ui and AI Elements look like the same choice on day one and behave like opposite choices later, because a dependency and a vendored source tree fail in opposite directions.
- A dependency upgrades without you. Bug fixes and accessibility work arrive on someone else's schedule and cost you a version bump. The price is that your customisations live in wrappers, overrides and the seams the API exposes — and a breaking change in a component you wrapped is a change you did not choose.
- Copied source never upgrades. Every fix after the day you copied is one you either port by hand or live without. The price is silent divergence: six months in, your
Messagecomponent and the registry's have nothing in common, and no diff tells you what you missed. - The tell is your customisation depth. If you will restyle and stop, the dependency is free maintenance. If your design system will rewrite the internals anyway — and in most product teams it will — copied source removes a layer of indirection you would otherwise fight.
There is a second-order effect worth naming. Copied components are reviewable: they sit in your repository, they show up in code review, and a supply-chain question about them is answered by reading them. A component library that renders model output is a rendering surface, and rendering agent output safely is a real category of bug, not a hypothetical one.
Where the run state lives, and what an interrupt costs
Ask each library the same awkward question — the agent is halfway through a plan, it needs the user to approve a step, and the user reloads the page — and the architectures separate immediately. CopilotKit answers with a protocol-level interrupt and shared state, which is the strongest answer and also the reason the runtime exists. AI Elements answers with a tool call that is waiting for input, carried in the stream, which is clean as long as your server can resume the stream. assistant-ui answers with whatever your transport does, which is honest: the primitives will render it, and resumability is your problem. Chainlit answers with a session-scoped ask-user step that is excellent inside one session and gone when the process cycles.
None of these is wrong. But "can a user approve a step tomorrow morning" is a durability question about your backend, and only one of the four pretends to answer it for you. If approval flows matter, decide the resumable-run design first and let the UI layer follow — approval and confirmation UX and durable state and resumability are the pages that constrain this choice.
Generative UI moves the question to the catalog
All four are now downstream of a protocol argument they did not start. A2UI, Google's framework-agnostic generative-UI spec, reached v0.9 in July 2026; MCP Apps shipped in January 2026 as the first official MCP extension, co-designed with OpenAI and absorbing the community MCP-UI work. AG-UI sits at a different layer — the runtime connection between an agent backend and the app — and the projects treat these as complementary rather than competing.
The practical consequence is the one we argued in the catalog post: whichever library renders your chat, the components an agent may compose are a set you enumerate, own and review. A library that makes it easy to render arbitrary model-authored markup is not saving you work; it is moving your design review to runtime and your security review to the server boundary. Judge each of these four on how hard it makes the enumerable case, not on how impressive the freeform demo looks.
Durability, because 2026 kept testing it
Chainlit's original team stepped back from active development on 1 May 2025; the project continues under community maintainers with a formal maintainer agreement and a steady 2.x release line. That is a better outcome than the alternative, and it is still a governance fact you should price. Flowise archived its own repository in August 2026 and its maintainers named coding agents as the reason. Langflow's owner changed hands when IBM completed its DataStax acquisition in November 2025.
- Ask what a fork costs. Forking a component library is a weekend. Forking a runtime that speaks a protocol is a quarter. Forking an application server whose front end you never had is a rewrite.
- Ask what the artefact is. Copied components are yours already. React primitives are replaceable in place. A protocol is re-implementable by anyone who can read the spec. A Chainlit app is Python handlers plus a UI you would have to rebuild.
- Ask who else depends on the layer. A protocol with several independent implementations survives one company losing interest; a component library with one vendor does not, however good it is today.
When to pick which
| Situation | Pick | Because |
|---|---|---|
| The agent must read and change state inside your app | CopilotKit | Shared state and protocol-level interrupts are the product, not an add-on |
| Next.js app, AI SDK already in the stack | AI Elements | Least glue, and the components land in your repo where your design system lives |
| Existing React app with its own transport and design system | assistant-ui | Claims the least; leaves your backend and streaming decisions intact |
| Python team, internal tool or research demo | Chainlit | Fastest path to a usable UI when nobody on the team wants to own a front end |
| Customer-facing surface with a strict design system | AI Elements or assistant-ui | Both let the design system win; the heavier options make you negotiate with theirs |
FAQ
Is CopilotKit an agent framework or a UI library?
Both, and that is the trade. It provides React surfaces and a runtime that speaks AG-UI, the agent-to-user protocol it developed with LangChain. If you only need a chat surface, you are adopting a protocol and a runtime you will not use; if you need the agent and the app to share state, nothing lighter does it properly.
Do AI Elements lock me into Vercel?
Not to the platform — the components are source files in your repository and run anywhere. The coupling is to the AI SDK's streaming protocol, which is what the components are built to consume. That is a real coupling, but it is at the transport rather than the host, and the AI SDK runs on any Node or edge runtime.
Is Chainlit safe to start a new project on in 2026?
For internal tools and demos, yes: it is Apache-2.0, community-maintained since the original team stepped back in May 2025, and still shipping. For a customer-facing product where you expect to diverge from the built-in UI, the cost of leaving is a rewrite of the front end you never owned, so decide that before the second sprint rather than after.
Can I mix them?
Common pairings work: assistant-ui or AI Elements components in front of an AG-UI backend, or AI Elements copied in and then edited into a design system that also serves non-agent surfaces. What does not work is running two runtimes that both think they own the thread state.
What about A2UI and MCP Apps?
They answer a different question — how an agent describes an interface — while these four answer how your application renders and drives a run. Pick the library for the coupling you want, then decide separately whether agent-authored UI enters your product at all, and from which catalog.
Further reading
On this wiki:
- Generative UI patterns — the component catalog as a contract.
- Approval and confirmation UX — the interrupt design that constrains this choice.
- Durable state and resumability — why "the user reloaded the page" is a backend question.
- Rendering agent output safely — the security half of a component library.
- Generative UI has two standards — A2UI versus MCP Apps, and who owns the catalog.