A plug-and-play React chatbot component supporting multiple AI providers (OpenAI, Anthropic, Mistral). Zero UI framework dependencies, fully typed with TypeScript, and highly customizable.
- Multiple AI Providers: OpenAI, Anthropic (Claude), and Mistral out of the box
- Zero UI Dependencies: Pure CSS with CSS variables for easy theming
- TypeScript Support: Fully typed with exported types
- Customizable Position: Place the chatbot in any corner of the screen
- Theming: Light/dark/auto themes with custom color support
- Markdown Support: Renders markdown in AI responses
- Responsive: Works on mobile and desktop
- Callbacks: Hooks for message events and errors
npm install react-ai-chat-widgetimport { Chatbot } from 'react-ai-chat-widget';
import 'react-ai-chat-widget/styles';
function App() {
return (
<Chatbot
aiConfig={{
provider: 'openai',
apiKey: 'your-api-key',
model: 'gpt-4',
systemPrompt: 'You are a helpful assistant.',
}}
/>
);
}| Prop | Type | Required | Description |
|---|---|---|---|
provider |
'openai' | 'anthropic' | 'mistral' |
Yes | AI provider to use |
apiKey |
string |
Yes | API key for the provider |
model |
string |
No | Model to use (defaults vary by provider) |
systemPrompt |
string |
No | System prompt for context |
maxTokens |
number |
No | Maximum tokens in response (default: 1024) |
temperature |
number |
No | Response randomness 0-1 (default: 0.7) |
| Prop | Type | Default | Description |
|---|---|---|---|
position |
'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' |
'bottom-right' |
Position on screen |
offsetX |
number |
24 |
Horizontal offset in pixels |
offsetY |
number |
24 |
Vertical offset in pixels |
chatWidth |
number | string |
400 |
Chat window width |
chatHeight |
number | string |
'70vh' |
Chat window height |
toggleIcon |
ReactNode |
Chat bubble icon | Custom toggle button icon |
toggleLabel |
string |
- | Text label for toggle button |
showToggleLabel |
boolean |
true |
Show/hide toggle label |
theme |
'light' | 'dark' | 'auto' |
'light' |
Color theme |
themeConfig |
ThemeConfig |
- | Custom theme colors |
welcomeMessage |
string | string[] |
- | Welcome message (random if array) |
placeholder |
string |
'Type your message...' |
Input placeholder |
closeOnClickOutside |
boolean |
true |
Close when clicking outside |
persistMessages |
boolean |
false |
Keep messages on close |
loadingText |
string |
'Thinking...' |
Loading indicator text |
onOpen |
() => void |
- | Called when chat opens |
onClose |
() => void |
- | Called when chat closes |
onMessageSent |
(message: string) => void |
- | Called when user sends message |
onMessageReceived |
(message: string) => void |
- | Called when AI responds |
onError |
(error: Error) => void |
- | Called on error |
<Chatbot
aiConfig={{
provider: 'openai',
apiKey: process.env.REACT_APP_OPENAI_KEY,
model: 'gpt-4', // or 'gpt-3.5-turbo'
}}
/><Chatbot
aiConfig={{
provider: 'anthropic',
apiKey: process.env.REACT_APP_ANTHROPIC_KEY,
model: 'claude-3-opus-20240229', // or 'claude-3-sonnet', 'claude-3-haiku'
}}
/>Note: Anthropic API requires CORS headers. For browser usage, you may need a proxy server or use their official SDK with server-side calls.
<Chatbot
aiConfig={{
provider: 'mistral',
apiKey: process.env.REACT_APP_MISTRAL_KEY,
model: 'mistral-large-latest', // or 'mistral-small-latest'
}}
/>Customize the appearance using CSS variables:
:root {
--chatbot-primary: #6366f1;
--chatbot-bg: #ffffff;
--chatbot-text: #1f2937;
--chatbot-user-bubble: #6366f1;
--chatbot-user-text: #ffffff;
--chatbot-assistant-bubble: #f3f4f6;
--chatbot-assistant-text: #1f2937;
--chatbot-border-radius: 12px;
--chatbot-font-family: system-ui, sans-serif;
}<Chatbot
aiConfig={config}
themeConfig={{
primaryColor: '#10b981',
backgroundColor: '#f0fdf4',
userBubbleColor: '#10b981',
assistantBubbleColor: '#d1fae5',
borderRadius: 16,
}}
/><Chatbot
aiConfig={config}
theme="dark"
/><Chatbot
aiConfig={config}
theme="auto"
/>Control the chat window dimensions with chatWidth and chatHeight:
<Chatbot
aiConfig={config}
chatWidth={380} // pixels
chatHeight={500} // pixels
/>You can also use string values for responsive sizing:
<Chatbot
aiConfig={config}
chatWidth="90vw" // viewport width
chatHeight="80vh" // viewport height
/>import { Chatbot } from 'react-ai-chat-widget';
import { FaRobot } from 'react-icons/fa';
<Chatbot
aiConfig={config}
toggleIcon={<FaRobot size={24} />}
toggleLabel="Ask AI"
/><Chatbot
aiConfig={config}
toggleLabel="Ask Me"
toggleIcon={
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3z" />
<path d="M5 19l1 3 1-3 3-1-3-1-1-3-1 3-3 1 3 1z" />
</svg>
}
/><Chatbot
aiConfig={config}
toggleIcon={<span style={{ fontSize: '24px' }}>🤖</span>}
toggleLabel="Chat"
/><Chatbot
aiConfig={config}
toggleLabel="Need Help?"
/><Chatbot
aiConfig={config}
welcomeMessage="Hi! How can I help you today?"
/><Chatbot
aiConfig={config}
welcomeMessage={[
"Hi! How can I help?",
"Hello! What can I do for you?",
"Hey there! Ask me anything!",
]}
/><Chatbot
aiConfig={config}
onOpen={() => console.log('Chat opened')}
onClose={() => console.log('Chat closed')}
onMessageSent={(msg) => console.log('User:', msg)}
onMessageReceived={(msg) => console.log('AI:', msg)}
onError={(err) => console.error('Error:', err)}
/>All types are exported for use in your application:
import type {
ChatbotProps,
AIConfig,
AIProvider,
ThemeConfig,
Message,
} from 'react-ai-chat-widget';For custom implementations, you can use the hooks directly:
import { useChat } from 'react-ai-chat-widget';
function CustomChat() {
const { messages, isLoading, sendMessage, addMessage } = useChat({
aiConfig: {
provider: 'openai',
apiKey: 'your-key',
},
});
// Build your own UI
}import { getProvider } from 'react-ai-chat-widget';
const provider = getProvider({ provider: 'openai', apiKey: 'your-key' });
const response = await provider.sendMessage(
[{ role: 'user', content: 'Hello' }],
config
);Here's a complete example of using the chat widget as a portfolio assistant that answers questions about your skills and experience:
"use client"; // For Next.js App Router
import { Chatbot } from "react-ai-chat-widget";
import "react-ai-chat-widget/styles";
// Import your portfolio data
import { experience, skills, technologies, socialLinks } from "@/lib/data";
// Build dynamic system prompt from your data
const systemPrompt = `You are a helpful AI assistant on my portfolio website.
## About Me
Full Stack Developer with 5+ years of experience specializing in Node.js, React, and cloud technologies.
## Work Experience
${experience.map((exp) => `- ${exp.company}: ${exp.designation}`).join("\n")}
## Technologies
${technologies.map((t) => t.name).join(", ")}
## Services
${skills.map((s) => `- ${s.service}`).join("\n")}
## Contact
- Email: ${socialLinks.email}
- LinkedIn: ${socialLinks.linkedin}
Be friendly, professional, and encourage visitors to reach out for collaboration.`;
export function PortfolioChat() {
return (
<Chatbot
aiConfig={{
provider: "mistral",
apiKey: process.env.NEXT_PUBLIC_MISTRAL_API_KEY || "",
model: "mistral-small-latest",
systemPrompt,
}}
position="bottom-right"
theme="dark"
chatWidth={380}
chatHeight={500}
welcomeMessage="Hi! I'm here to help you learn more about my work and skills. What would you like to know?"
placeholder="Ask me anything..."
themeConfig={{ primaryColor: "#8b5cf6" }}
toggleLabel="askMe"
toggleIcon={
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<path d="M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5L12 3z" />
</svg>
}
/>
);
}Then add it to your layout:
// app/layout.tsx
import { PortfolioChat } from "@/components/portfolio-chat";
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<PortfolioChat />
</body>
</html>
);
}This approach keeps your chatbot's knowledge in sync with your portfolio data automatically!
| Feature | react-ai-chat-widget | Most Alternatives |
|---|---|---|
| AI Providers | Built-in OpenAI, Anthropic, Mistral | Usually require custom integration |
| Dependencies | Zero UI framework deps (pure CSS) | Often require MUI, styled-components |
| Setup | Single component, pass API key & go | Often need backend setup |
| Styling | CSS variables for easy theming | Many use CSS-in-JS |
| Bundle Size | Lightweight (~25KB) | Often larger due to dependencies |
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
MIT
See CONTRIBUTING.md for contribution guidelines.
Happy coding!
