A customizable React + TypeScript chat component for AI assistants, SaaS applications, internal tools, and chatbot interfaces.
- π¨ Light & Dark themes with a consistent internal color system
- π¨ Custom primary color
- π€ AI & User avatars (image or custom fallback)
- ποΈ Fully customizable header, empty state, input, and send button
- π¬ Modern chat interface
- π Markdown rendering (headings, lists, links, blockquotes, inline code, tables)
- π Syntax highlighted code blocks with copy button
- π Copy message button with accessible feedback
- β¨οΈ Enter to send, Shift + Enter for new lines
- β¨οΈ Animated typing indicator and send-button loading state
- β° Message timestamps with optional formatter
- π± Responsive design with no horizontal overflow
- β‘ TypeScript support with exported types
npm install react-ai-chatkitor
yarn add react-ai-chatkitor
pnpm add react-ai-chatkitimport { AIChatBox } from "react-ai-chatkit";
import type { Message } from "react-ai-chatkit";
const messages: Message[] = [
{
id: "1",
text: "Hello! How can I help you?",
sender: "ai",
},
];
export default function App() {
return (
<AIChatBox
messages={messages}
onSendMessage={(message) => console.log(message)}
/>
);
}import { AIChatBox } from "react-ai-chatkit";
import type { Message } from "react-ai-chatkit";
const messages: Message[] = [
{
id: "1",
text: "Hello! How can I help you?",
sender: "ai",
timestamp: "10:00",
},
];
export default function App() {
return (
<AIChatBox
messages={messages}
onSendMessage={(message) => console.log(message)}
title="AI Assistant"
subtitle="Online"
theme="light"
primaryColor="#6366f1"
width="500px"
height="600px"
aiAvatarFallback={<span>π€</span>}
userAvatarFallback={<span>π</span>}
emptyStateTitle="How can I help?"
emptyStateDescription="Ask me anything."
placeholder="Type your message..."
maxLength={500}
autoFocus
sendButtonText="Send"
timestampFormatter={(timestamp) => `at ${timestamp}`}
/>
);
}<AIChatBox
messages={messages}
onSendMessage={handleSend}
header={
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
<strong>Support</strong>
</div>
}
headerActions={<button type="button">Settings</button>}
sendButtonContent={
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="m5 12 4 4L19 6" />
</svg>
}
userMessageStyle={{ marginTop: 4 }}
aiMessageClassName="ai-message-box"
/><AIChatBox
messages={messages}
onSendMessage={handleSend}
isTyping={isWaiting}
isSending={isWaiting} // disables the send button and shows a spinner
/>| Prop | Type | Default | Description |
|---|---|---|---|
| messages | Message[] |
Required | Chat messages |
| onSendMessage | (message: string) => void |
undefined |
Called when a message is sent |
| title | string |
"React AI Chatbox" |
Header title |
| subtitle | string |
undefined |
Optional header subtitle |
| header | ReactNode |
undefined |
Replaces the default header content |
| headerActions | ReactNode |
undefined |
Action content shown on the right side of the header |
| theme | "light" | "dark" |
"dark" |
Theme |
| primaryColor | string |
#7c3aed |
Primary accent color |
| width | string | number |
"450px" |
Component width |
| height | string | number |
"520px" |
Component height |
| placeholder | string |
"Type your message..." |
Input placeholder |
| disabled | boolean |
false |
Disable input |
| isTyping | boolean |
false |
Show typing indicator |
| isSending | boolean |
false |
Disable send and show a spinner while sending |
| showHeader | boolean |
true |
Show header |
| showAvatars | boolean |
true |
Show avatars |
| aiAvatar | string |
undefined |
AI avatar image URL |
| userAvatar | string |
undefined |
User avatar image URL |
| aiAvatarFallback | ReactNode |
Robot icon | Content shown when no AI avatar image is set |
| userAvatarFallback | ReactNode |
Person icon | Content shown when no user avatar image is set |
| aiMessageClassName | string |
undefined |
Class added to AI message rows |
| aiMessageStyle | React.CSSProperties |
undefined |
Style added to AI message rows |
| userMessageClassName | string |
undefined |
Class added to user message rows |
| userMessageStyle | React.CSSProperties |
undefined |
Style added to user message rows |
| showCopyButton | boolean |
true |
Show the message copy button |
| showSendButton | boolean |
true |
Show the send button |
| sendButtonText | string |
"Ask AI" |
Send button text (and accessible label for custom content) |
| sendButtonContent | ReactNode |
undefined |
Custom send button content/icon |
| showTimestamps | boolean |
true |
Show timestamps |
| timestampFormatter | (timestamp: string) => string |
undefined |
Format the rendered timestamp |
| emptyStateTitle | string |
"Start a conversation" |
Empty state title |
| emptyStateDescription | string |
"Send a message to begin chatting." |
Empty state description |
| emptyStateContent | ReactNode |
undefined |
Replaces the default empty state content |
| inputProps | TextareaHTMLAttributes<HTMLTextAreaElement> |
undefined |
Native textarea props |
| inputClassName | string |
undefined |
Class added to the textarea |
| inputStyle | React.CSSProperties |
undefined |
Style added to the textarea |
| inputContainerClassName | string |
undefined |
Class added to the input container (footer) |
| inputContainerStyle | React.CSSProperties |
undefined |
Style added to the input container (footer) |
| maxInputLength | number |
undefined |
Maximum input length (deprecated alias of maxLength) |
| maxLength | number |
undefined |
Maximum input length; prevents typing beyond the limit |
| autoFocus | boolean |
false |
Focus the textarea automatically on initial render |
| className | string |
undefined |
Class added to the component root |
| style | React.CSSProperties |
undefined |
Style added to the component root |
interface Message {
id: string;
text: string;
sender: "user" | "ai";
timestamp?: string;
}The internal color system is exported for custom styles:
import { getChatColors } from "react-ai-chatkit";
const colors = getChatColors("dark");
// { background, text, border, aiBubble, inputBackground, mutedText, success }const aiMessage = {
sender: "ai",
text: `
# Welcome
Here is some code:
\`\`\`tsx
function Button() {
return <button>Hello</button>;
}
\`\`\`
`,
};Markdown with tables, lists, quotes, and links is supported out of the box.
import { AIChatBox } from "react-ai-chatkit";
import type {
AIChatBoxProps,
ChatColors,
ChatTheme,
Message,
} from "react-ai-chatkit";
const config: AIChatBoxProps = {
messages: [],
onSendMessage: (message: string) => console.log(message),
theme: "dark",
};
export default function App() {
return <AIChatBox {...config} />;
}- π GitHub
- π¦ npm
- π Report an issue
MIT
