- Home>
- React
React for AI Copilots and HITL Interfaces

Bitontree builds React interfaces for AI copilots, review queues, human-in-the-loop workflows, and operational dashboards: the application layer your production AI ships inside. We build them and keep improving them after launch.
- Copilot and chat interfaces
- Human-in-the-loop review queues
- Operational AI dashboards
- Built and run in production
Where React Fits in a Production AI System
React is where people meet your AI. The model can be excellent, but if the interface hides what the agent is doing, buries the approval step, or freezes during a slow response, the system fails in front of the person using it.
We build React interfaces for the parts of AI UX that are genuinely hard: streaming responses token by token, showing tool-call progress, rendering partial results, and giving a reviewer a clear way to approve, edit, or reject what the model produced.
Use React when you need:
- A copilot or chat interface embedded in a product your users already live in
- Human-in-the-loop review queues where people control what agents do before it counts
- Operational dashboards showing agent runs, outcomes, and the cases that need attention
- AI widgets dropped into an existing application without a framework migration
Reach for Next.js instead when the AI feature is a standalone product or needs server rendering and routing of its own. We cover that choice honestly on the Next.js page.
What We Build With React
The interfaces that make production AI usable.
Copilot & Chat Interfaces
Embedded assistants with streaming responses, history, and clear handling of tool calls and errors.
Streaming Response UI
Token-by-token rendering with optimistic states and progress, so the experience feels live under real model latency.
HITL Review Queues
Approve, edit, and reject interfaces with full context and an audit trail, putting a person in control of agent output.
Operational Dashboards
Views over agent runs, accuracy, cost, and exceptions, so the team running the AI can actually see it.
Embedded AI Widgets
Self-contained React components that drop AI features into the application you already have.
AI State Design Systems
Loading, partial, failed, and degraded states designed once and reused, because AI interfaces live in those states constantly.
Reference Architecture for a React AI Interface
A React AI interface is more than a chat box with a text stream. Once a real product depends on it, the front end becomes a layered system: a transport layer that reads the model stream, a state layer that holds the run, a render layer that shows tool calls and model output safely, and a control layer for review, roles, and audit. Skip a layer and the interface demos fine, then leaks raw HTML from a model, freezes on a slow response, or lets a viewer approve something they should never see. This is the layout we converge on.
Each layer does one job:
- Streaming client: The interface reads the response as it arrives instead of waiting for a finished blob. We consume Server-Sent Events or a
fetchstream with aReadableStreamreader, parse the chunks, and push tokens into state as they land. Often we sit the Vercel AI SDK (useChat,useCompletion) on top of this so the transport, abort handling, and message bookkeeping are battle-tested rather than hand-rolled. This is what makes a slow model feel alive rather than frozen. - Token buffer and optimistic state: Streamed tokens land in a buffer that the UI renders progressively, while the user's own message shows instantly with an optimistic update. We keep this run state in Zustand or Redux Toolkit when a run has real structure (pending tool calls, partial messages, retries), and use React Query or SWR for the request-shaped data around it (history, saved threads, queue items) so caching, refetching, and invalidation are not reinvented per screen.
- Tool-call status rendering: Agents call tools, and people need to see that happening. We render each tool call as a distinct status element, pending, running, succeeded, or failed, with its arguments and result, so a long agent run reads as visible progress instead of a spinner that might be stuck. The status model maps directly to the events the agent service emits.
- Safe-render layer: Everything a model writes is untrusted input. We never drop raw model output into
dangerouslySetInnerHTML. Markdown is parsed, then constrained to an allowlist of tags and attributes, and the resulting HTML is sanitized with DOMPurify before it reaches the DOM. Links are constrained, and code blocks render as inert text. Prompt-injected content cannot execute a script, smuggle an event handler, or fire a real action from inside a rendered message. - Review-queue state and audit log: For human-in-the-loop work, the interface holds a queue of items awaiting a decision, each with the full context an approver needs and the actions they can take. Every approve, edit, and reject writes an audit entry with who decided and when, so the record is defensible later. The queue state is the front-end mirror of the agent's interrupt and resume points.
- Role-gated views: Reviewers, operators, and read-only viewers see only the data and actions their role allows. Gating happens in the component tree and is enforced again at the API, so a hidden button is never the only thing standing between a viewer and a privileged action.
The interface does not talk to a model directly. It connects to a Node streaming API that proxies the model, holds credentials, and shapes the event stream, which in turn calls the Python agent service where the agent logic, tools, and interrupts live. React renders the stream and the review surface; the server layers own the secrets, the orchestration, and the decisions that count.
For data-dense surfaces, an agent-run dashboard with thousands of rows, or a review queue that never stops growing, we virtualize with react-window or TanStack Virtual so only the visible rows mount. Combined with memoization and disciplined re-render boundaries, that keeps a heavy operational view smooth instead of janky as the data grows.
React vs Next.js vs Plain SPA for an AI Interface
Five decisions that settle which React setup fits an AI feature. The honest split is about where the feature lives and who owns the server layer, not which name is trendier.
| Decision point | React (SPA / embedded) | Next.js | Plain SPA (no React) |
|---|---|---|---|
| Where the feature lives | Inside an app you already run, or dropped in as a widget | A standalone AI product or tool with its own front door | A small embed where pulling in React is not worth it |
| Rendering & streaming | Client rendering, with the stream read straight from your API | Server and client rendering, with streamed Server Components and route handlers | Manual DOM updates, which get painful once streaming state grows |
| Server layer for the AI calls | Your existing backend, called over fetch or WebSocket | Built-in route handlers and server actions proxy the model calls | Whatever backend you have, wired by hand |
| Routing & SEO surface | Lives behind your app shell, so little new public SEO surface | File-based routing and SSR give you indexable, shareable pages | None to speak of; it is a self-contained widget |
| Best fit | In-product copilots, review queues, internal operational panels | AI products, public dashboards, marketing-adjacent app surfaces | Tiny one-off chat embeds with almost no review or dashboard state |
React AI Interfaces We Build by Pattern
The interface patterns we reach for most when a production AI feature meets the people who use it.
Embedded Product Copilot
A streaming copilot that lives inside the app your users already work in. It reads the model stream token by token, shows tool-call progress, and keeps a thread history, so the assistant feels like part of the product rather than a bolted-on chat box.
Human-in-the-Loop Review Queue
An approve, edit, and reject surface that puts a person in front of agent output before it counts. Each item carries full context and writes an audit entry, which is usually the difference between an agent you can trust and one you cannot.
Agent Operations Dashboard
A virtualized view over agent runs, outcomes, and the cases that need attention. react-window or TanStack Virtual keep thousands of rows smooth, so the team running the AI can actually see what it is doing.
Streaming Document Review
A side-by-side surface where the model drafts and a person corrects, with sanitized markdown rendering so extracted or generated content never injects into the page. Edits and approvals are recorded against the source document.
Drop-In AI Widget
A self-contained React component that adds an AI feature to an application you already run, talking to your backend with no framework migration. It ships its own loading, partial, and failure states so it behaves predictably wherever it lands.
Real-Time Operations View
A live panel fed by AI services over a streaming connection, where exceptions surface as they happen and an operator can act on them. The same streaming-state discipline that powers a copilot keeps the view consistent under constant updates.
How We Build and Run React AI Interfaces
From the first flow to an interface we keep improving in production.
AI UX Flows First
We design the streaming, partial-result, and review interactions before anything else, because that is where AI UX succeeds or fails.
Streaming & Progress
Token streaming, tool-call status, and optimistic UI, so slow models never look like frozen screens.
Safe Output Rendering
Model output is sanitized and rendered defensively, so prompt-injected content never executes in your interface.
Review & Audit Components
Approve, edit, and reject flows that record who decided what and when.
Accessibility & States
Loading, error, and degraded states designed deliberately, accessible by default.
Performance
Memoization, virtualization, and bundle discipline, so data-dense AI dashboards stay fast.
Iteration After Launch
We watch how people actually use the interface and keep tuning flows, copy, and states.
Safe Rendering & UX Governance for AI Interfaces
What keeps an AI interface trustworthy for the people using it.
Sanitized Model Output
Everything a model writes is treated as untrusted input: sanitized, escaped, and never blindly injected into the page.
Prompt-Injection Defense at the UI
Links, actions, and rich content from model output are constrained, so injected instructions cannot trigger real actions from the interface.
Roles & Permissions
Reviewers, operators, and viewers see exactly the data and actions their role allows.
Audit of Human Decisions
Every approve, edit, and reject is recorded with who and when, so decisions stay accountable.
Honest Failure States
When the model is slow or wrong, the interface says so and offers a path forward, instead of pretending nothing happened.
React AI Interfaces by Industry
Where these interfaces do their work.
Healthcare
Clinician review queues and patient-facing flows with audit trails, built HIPAA-aware.
Logistics
Exception dashboards that let dispatchers see and act on what agents flag.
Legal
Document review interfaces where lawyers approve or correct AI output.
SaaS
In-product copilots and AI features inside the app your customers already use.
Ecommerce
Support copilots and catalog tools for merchandising and operations teams.
Manufacturing
Plant and operations dashboards fed by AI services in near real time.
Production Patterns We've Shipped
Real builds whose interface patterns we reuse for React AI work.
Financial Analytics Platform
A data-dense reporting product. The dashboard and rendering patterns we reuse for AI operational views.
GrowStack AI
An AI product with a real user-facing interface. The copilot and workflow patterns we apply to AI product surfaces.
Crypto Support Chatbot
A high-volume support chat experience. The streaming and conversation patterns that carry into AI interfaces.
Timeline & Engagement
Roughly how a React AI interface comes together.
Discovery & Design (1-3 weeks)
We map the flows, the AI interactions, and the data the interface needs.
First Working Interface (3-6 weeks)
A usable interface in your environment: core flows, streaming, and the first agent integrations.
Production Deployment (6-12+ weeks)
Hardening, accessibility, performance, and full coverage, then deployment with monitoring.
Ongoing Iteration (continuous)
We keep improving the interface based on how people actually use it.
Frequently Asked Questions
Why does the interface matter so much for AI systems?

Because trust is built or lost at the interface. A model can be excellent and still fail in front of a user if the screen freezes during a slow response, hides what the agent is doing, or buries the approval step. Streaming output, visible tool-call progress, honest failure states, and a real review path are what make people rely on an AI system instead of quietly working around it. The interface is where the system's behavior becomes legible to the person responsible for it.
React, Next.js, or a plain SPA for our AI feature?

It comes down to where the feature lives and who owns the server layer. Use React when you are embedding AI into an application you already run, since a component talking to your backend is the lighter, faster path. Reach for Next.js when the AI feature is a standalone product that needs its own routing, server rendering, and route handlers to proxy model calls. A plain SPA only makes sense for a tiny one-off embed with almost no review or dashboard state. We pick based on the feature, not on fashion, and we cover the Next.js trade-off honestly on the Next.js page.
Which React data and streaming libraries do you use for AI UIs?

For the streaming transport we read Server-Sent Events or a fetch stream with a ReadableStream reader, and we often sit the Vercel AI SDK (useChat, useCompletion) on top so abort handling, message bookkeeping, and reconnection are not hand-rolled. Run state, the structured shape of a single agent run with its pending tool calls and partial messages, lives in Zustand or Redux Toolkit. The request-shaped data around it, thread history, saved sessions, and queue items, goes through React Query or SWR so caching and invalidation are handled once. We choose per surface rather than forcing one tool everywhere.
How do you render model output safely?

Everything a model writes is treated as untrusted input. We never inject raw output through dangerouslySetInnerHTML. Markdown is parsed and then constrained to an allowlist of tags and attributes, the resulting HTML is sanitized with DOMPurify, links are constrained, and code blocks render as inert text. The result is that prompt-injected content cannot run a script, smuggle an event handler, or trigger a real action from inside a rendered message. The safe-render layer is a deliberate part of the architecture, not an afterthought.
How do you virtualize a dense agent dashboard?

When a dashboard holds thousands of agent runs or a review queue that keeps growing, we virtualize the list with react-window or TanStack Virtual so only the rows in view actually mount. We pair that with memoization on row components and tight re-render boundaries, so a streamed update to one run does not re-render the whole table. The effect is an operational view that stays smooth as the data grows, instead of one that degrades the moment real volume arrives.
Can you build a human review step into our workflow?

Yes. Approve, edit, and reject queues with full context and an audit trail are one of the most common things we build, and usually the line between a safe agent and a risky one. On the front end this is a queue of items awaiting a decision, each mirroring an interrupt point in the agent service, with every decision recorded against who made it and when. The same review surface is where role gating matters most, so the right people see the right actions.
How does the React interface connect to our agents and backend?

The interface does not talk to a model directly. It connects to a Node streaming API that proxies the model, holds credentials, and shapes the event stream, and that service calls the Python agent service where the agent logic, tools, and interrupts live. React renders the stream and the review surface, while the server layers own the secrets, the orchestration, and the decisions that count. That separation keeps keys out of the browser and lets the same interface sit in front of whatever model or agent runtime you run.
How do you handle roles, permissions, and audit in the UI?

Reviewers, operators, and read-only viewers see only the data and actions their role allows. Gating happens in the component tree so the UI reflects the role, and it is enforced again at the API so a hidden button is never the only thing protecting a privileged action. Every consequential decision, an approval, an edit, a rejection, is written to an audit log with the person and the timestamp, which is the basis for any later compliance or incident review. We design sensitive workflows, including healthcare ones, to be HIPAA-aware. We do not claim certification, but we build with the access controls and isolation that sensitive data calls for.
Do you keep working on the interface after launch?

Yes. We watch how people actually use the interface and keep tuning flows, copy, states, and performance, because the first version of an AI interface is never the last. Real usage surfaces the slow paths, the confusing states, and the review steps people skip, and we fix those on real traffic. We build and run. We do not just build and hand off.
Let's build your React AI interface
Tell us about the product and the AI behind it.
6+
Years Of Experience
40+
Skilled Professionals
105+
Projects Delivered
35+
Global Clientele Served