Open-source ยท Angular ยท LangGraph & AG-UI
The AI agent UI framework for Angular.
Chat, threads, approvals, and generative UI on Signals and DI. Your backend stays where it is.

MIT ยท Angular 20โ22 ยท no account, no cloud
Reliable to the core
Audited, scored, published.
Not self-reported โ every number links to its source.
#8 of 119
Of all agent frameworks ranked
hvtracker.net8.2 /10
OpenSSF Scorecard, official scan
scorecard.devHVTrust supply-chain grade, live
hvtracker.net/agents20โ22
Angular majors supported, CI-tested
npmjs.com
Runtime parity
One Angular UI. Two runtime adapters. The same contract.
@threadplane/chat consumes Agent, not LangGraphAgent or an AG-UI client. Swap the adapter without rewriting the Angular component tree.
What changes app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideAgent } from '@threadplane/langgraph';
export const appConfig: ApplicationConfig = {
providers: [
provideAgent({ apiUrl: 'http://localhost:2024', assistantId: 'agent' }),
],
};What does not same in both
import { Component } from '@angular/core';
import { ChatComponent, type Agent } from '@threadplane/chat';
@Component({
imports: [ChatComponent],
template: `<chat [agent]="agent" />`,
})
export class SupportAgentComponent {
// injectAgent() comes from the adapter you chose above;
// the component only depends on the runtime-neutral Agent contract.
protected readonly agent: Agent = injectAgent();
}Not every backend emits every capability. Interrupts, subagents and checkpoints depend on what the runtime sends. Choose an adapter โ
How it works
From agent endpoint to Angular UI in three steps.
Choose an adapter
Connect LangGraph or an AG-UI endpoint, or start with a fake agent. This is the only file that knows which runtime you run.
import { ApplicationConfig } from '@angular/core'; import { provideAgent } from '@threadplane/langgraph'; export const appConfig: ApplicationConfig = { providers: [ provideAgent({ apiUrl: 'http://localhost:2024', assistantId: 'agent' }), ], };Inject signal-shaped state
provideAgent() once, injectAgent() where the UI needs messages, status, errors, tool progress and thread actions.
import { Component } from '@angular/core'; import { injectAgent } from '@threadplane/langgraph'; import { ChatComponent } from '@threadplane/chat'; @Component({ imports: [ChatComponent], template: `<chat [agent]="agent" />`, }) export class SupportAgentComponent { protected readonly agent = injectAgent(); }Render the experience you own
Use the chat compositions, the headless primitives, or register your own design-system components for generated UI.
import { ApplicationConfig } from '@angular/core'; import { provideViews, views } from '@threadplane/render'; import { KpiCardComponent } from './kpi-card.component'; import { DisruptionsTableComponent } from './disruptions-table.component'; export const appConfig: ApplicationConfig = { providers: [ // Generated UI can render these components and nothing else. provideViews(views({ KpiCard: KpiCardComponent, DisruptionsTable: DisruptionsTableComponent, })), ], };
Stream
The UI stays reactive through tokens, tools, errors, and state changes.
injectAgent() hands back signals: messages(), status(), error(), isLoading(), and tool progress. Nothing to subscribe to, nothing to tear down.
Persist
A user can leave, return, inspect history, and continue.
Thread selection, history, branch and replay UI in the Angular app. Durability itself comes from the runtime and persistence layer you connect โ Threadplane exposes it, it does not fake it.
Approve
Irreversible work pauses for a human decision.
interrupt() freezes the run inside the checkpoint. Your UI renders the proposal; submit({ resume }) continues with the decision on the record.
Render
Agent output becomes components from your design system.
The agent emits constrained structured output. Angular renders registered components โ json-render and A2UI both speak it โ with per-component fallback and a readiness gate. No generated code runs.
Test
Verify UI behavior without a model or backend.
provideFakeAgent() streams canned tokens in-process; mock transports script tool calls and interrupts. Your component specs stay deterministic and fast.
import { TestBed } from '@angular/core/testing';
import { provideFakeAgent } from '@threadplane/langgraph';
import { SupportAgentComponent } from './support-agent.component';
it('renders the streamed reply', async () => {
TestBed.configureTestingModule({
imports: [SupportAgentComponent],
providers: [provideFakeAgent({ tokens: ['Hello', ' from', ' Threadplane'], delayMs: 0 })],
});
const fixture = TestBed.createComponent(SupportAgentComponent);
fixture.detectChanges();
const textarea: HTMLTextAreaElement = fixture.nativeElement.querySelector('textarea');
textarea.value = 'What can Threadplane do?';
textarea.dispatchEvent(new Event('input'));
fixture.detectChanges();
const send: HTMLButtonElement = fixture.nativeElement.querySelector('button[aria-label="Send message"]');
send.click();
await fixture.whenStable();
fixture.detectChanges();
expect(fixture.nativeElement.textContent).toContain('Hello from Threadplane');
});See it running
One chat UI. Two runtimes. Same code.
The identical Threadplane chat surface, running live against a LangGraph backend and an AG-UI backend. Switch tabs to compare โ the front end never changes.
Video loops instantly ยท click Launch to open the live, interactive demo ยท no signup
For coding agents
Give your coding agent the Angular agent UI playbook.
Threadplane publishes maintained, machine-readable setup context. Start with a fake agent, verify the Angular surface, then connect LangGraph or AG-UI.
Add Threadplane to this Angular application.
1. Read https://threadplane.ai/AGENTS.md and the current Threadplane quickstart.
2. Inspect this repository's Angular version, application configuration, design
system, test runner, and existing agent/backend code.
3. Begin with Threadplane's provideFakeAgent() path so the UI can be verified
without a server or LLM.
4. Render the smallest accessible <chat> experience using the app's existing
layout and styles.
5. Add a focused test for the integration.
6. After the fake path passes, explain the exact configuration needed for
either LangGraph or AG-UI. Do not invent credentials, endpoint URLs, or
backend capabilities.
7. Run the repository's relevant lint, test, and build commands and report
every changed file.Why Threadplane
What you start with, and what Threadplane adds.
| Starting point | What it gives you | What Threadplane adds |
|---|---|---|
| Raw SSE or stream SDK | Transport and events | Angular state model, chat UX, threads, approvals, generated UI, recovery, tests |
| Backend agent framework | Agent runtime and orchestration | The production Angular application and interaction layer |
| Generative-UI renderer | Structured UI rendering | Full agent UI, adapters, thread UX, interrupts, testing, and render support |
| React-first agent UI | Mature React patterns | Native Angular Signals, DI, templates, components, and testing |
Field report
The last-mile gap in Angular AI.
Six production-readiness dimensions
18 pages
Error boundaries, fallbacks, observability, deploy
concrete patterns
No vendor pitch โ what we learned shipping it
free
Already on the list? Download the PDF directly.
For teams
Shipping inside a large Angular platform?
Bring your backend, security model, and design system. Work directly with Threadplane engineers on architecture, rollout, testing, and production hardening.
A working agent demo on your domain
your data
Hardened error, fallback, observability patterns
production-ready
Deploy-ready integration
your CI/CD
Team trained on the framework
runbook, yours
Questions
Frequently asked questions.
Is Threadplane a backend agent framework?
Does Threadplane require LangGraph?
@threadplane/ag-ui connects any AG-UI-compatible backend, and @threadplane/langgraph is the direct LangGraph adapter. AG-UI on ThreadplaneWhat is the difference between the LangGraph and AG-UI adapters?
Agent contract. LangGraph adds native threads, checkpoints, history, and branch mapping; AG-UI maps the protocol's events and depends on what the backend emits. Choosing an adapterWhere are threads and checkpoints stored?
Can I use my existing Angular component library and design system?
Does generated UI execute arbitrary code?
Can I test the UI without a model or a live backend?
provideFakeAgent() streams canned tokens in-process, and mock transports script tool calls and interrupts. Try it without a backendWhich Angular versions are supported?
Does Threadplane require a hosted service or an account?
What does Threadplane report about my application?
How does Threadplane differ from a raw streaming SDK?
How does Threadplane compare with other Angular agent UI libraries?
Prove the Angular UI before you connect the backend.
Start with a fake agent, render a real Threadplane surface, then swap in LangGraph or AG-UI when the integration is ready.
MIT ยท no account, no cloud ยท Talk to an engineer
Blog
Recent articles
What Changes in Your Angular Code When the Agent Runtime Changes
AG-UI and LangGraph land on the same Angular contract. Here is what actually differs โ and which differences are the protocol, not the adapter.
We Measured the Runtime Swap: Three Non-LangGraph Backends, One Angular Contract
Strands, Microsoft Agent Framework, and Mastra against the neutral Agent contract. Messages, tools, and state ported. Both defects we found were ours.
What Fixture Replay Can't Catch
Our agent e2e suite replaces the model and keeps everything else real. That buys determinism by deleting time โ and one bug class disappears with it.