@personaai/react is the official React SDK for Persona — a
set of hooks and a context provider that let you build a full-featured chat UI against any
Persona backend (Express, NestJS, or raw runtime) without writing fetch calls, SSE parsers, or
state management by hand.
v0.3.2, current release. Requires React 18+.
Install
react >= 18. No other packages are required.
Prerequisites
You need a running Persona backend — either:@personaai/nextjsmounted in your Next.js app@personaai/expressmounted in your Express app@personaai/nestjsconfigured in your NestJS module- A raw runtime on any other host
On Next.js, install
@personaai/nextjs instead of this package.
It re-exports everything documented here behind a 'use client' boundary — same hooks, same
provider, one install for both halves of the app./chat,
/threads, /files, /memory, /health, /agents) — it never talks directly to
persona.hasanraiyan.me or holds any credential.
Set up the Provider
Wrap your app (or the subtree that needs chat) in<PersonaProvider>. It takes three things:
baseUrl— where your Persona backend is mounted (e.g.http://localhost:3000/api/persona)getAuthToken— an async getter for the user’s Bearer token (Clerk, JWT, session, whatever your app uses). Omit if your backend doesn’t require auth.defaultAgentId— optional; lets you skip passingagentIdto every hook call.
fetchWithAuth
available to every hook downstream. Every hook must be called inside this provider.
Minimal chat example
Here’s a complete, working chat UI in one file — streaming messages, input box, and error handling:useChat hook handles SSE parsing, message state, abort controllers, and thread management
internally.
Adding thread history
Wrap your chat in a sidebar that lists past conversations:How sendMessage works
sendMessage is the raw send function. It takes:
content(optional) — the message text. If omitted, uses the currentinputvalue.overrideOptions(optional) —{ agentId?, threadId?, resume? }to override the hook-level defaults for this specific send.
threadId is not set and this is the first message, useChat will fail unless your
backend supports implicit thread creation. Use useThreads().createThread() first if you need
explicit thread management.
Handling interrupts (HITL & clarifications)
When the agent pauses for human-in-the-loop approval or a clarification question, the hook exposes aninterrupt object. Render it and call resumeInterrupt when the user responds:
Full return value of useChat
Next steps
- Hooks reference — every hook in depth, with full parameter/return docs.
- Streaming events — the AG-UI event shapes
useChatconsumes, and how to use theonEventcallback. - Types reference — every exported type, interface, and alias.