npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@codexpro.ai/ai-chatbot

v2.0.3

Published

A production-ready React chat widget for AI assistants with enterprise-grade architecture

Readme

AI ChatBot Library v2.0.2

A production-ready React library for building AI chatbot interfaces with enterprise-grade architecture. Built with TypeScript, featuring service layer architecture, comprehensive error handling, and full customization support.

✨ Tailwind CSS v4 is bundled - No need to install Tailwind separately! The library includes all necessary styles.

Features

  • 🏗️ Enterprise-grade architecture with service layer
  • 🎨 Fully customizable UI (colors, branding, themes)
  • 📝 Markdown rendering for rich text responses (bold, lists, code blocks, links)
  • 📎 File attachments (images, videos, audio)
  • 🎤 Voice recording with WhatsApp-style interface
  • 💬 Real-time chat with typing indicators
  • 🔄 Automatic retry with exponential backoff
  • 💾 Conversation persistence
  • 📱 Responsive design
  • 🌐 Full TypeScript support with enums
  • ⚡ Lightweight and performant
  • 🛡️ Robust error handling with typed errors
  • 📊 Structured logging for debugging
  • ✅ Configuration validation

Installation

npm install ai-chatbot
# or
yarn add ai-chatbot
# or
pnpm add ai-chatbot

Quick Start

EchoMind Integration

For EchoMind projects, you can use the simplified props instead of constructing the full endpoint:

<AiChatWidget
  apiBase="http://localhost:3030/api"
  projectId="your-project-uuid"
  userId="user-123"
  branding={{
    name: "Support Bot"
  }}
/>

This automatically constructs the endpoint as {apiBase}/{projectId}/query and handles conversation persistence.

Basic Usage

import { AiChatWidget } from 'ai-chatbot'

export default function App() {
  return (
    <AiChatWidget
      apiEndpoint="https://your-api.com/chat"
      branding={{
        name: "Support Bot",
        companyName: "Your Company"
      }}
    />
  )
}

Next.js Usage (App Router)

Create a client component wrapper:

// components/ChatWidget.tsx
'use client'

import { AiChatWidget } from 'ai-chatbot'

export default function ChatWidget() {
  return (
    <AiChatWidget
      apiEndpoint="https://your-api.com/chat"
      branding={{
        name: "Support Bot"
      }}
      theme={{
        primaryColor: "#3b82f6",
        headerBackground: "#1e40af"
      }}
    />
  )
}

Then use it in your layout or page:

// app/layout.tsx
import ChatWidget from '@/components/ChatWidget'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <ChatWidget />
      </body>
    </html>
  )
}

Backend API Integration

Your backend needs to handle POST requests to the apiEndpoint you configure. The widget sends structured data and expects a specific response format.

API Endpoint

The widget makes POST requests to your configured endpoint:

<AiChatWidget apiEndpoint="https://your-api.com/chat" />

Request Payload

The widget sends a POST request with the following structure:

JSON Request (Text Messages)

{
  "message": "User's message text",
  "conversationId": "conv-abc123",
  "history": [
    {
      "role": "user",
      "content": "Previous question"
    },
    {
      "role": "assistant", 
      "content": "Previous answer"
    }
  ],
  "sessionId": "session-xyz",
  "userMetadata": {
    "Authorization": "Bearer token"
  }
}

FormData Request (With File Attachments)

When users upload files, the request is sent as multipart/form-data:

message: "Check this image"
conversationId: "conv-abc123"
history: "[{...}]" (JSON stringified)
sessionId: "session-xyz"
userMetadata: "{...}" (JSON stringified)
file_0: <File object>
file_1: <File object>
attachments: "[{id, type, name, size, mimeType}]" (JSON stringified)

Request Fields

| Field | Type | Required | Description | |-------|------|----------|-------------| | message | string | Yes | The user's message text | | conversationId | string | Yes | Unique conversation identifier (auto-generated) | | history | Array<{role, content}> | Yes | Simplified message history with role and content only | | sessionId | string | No | Session identifier (from config or userId) | | userMetadata | object | No | Custom headers/metadata from config | | attachments | array | No | File metadata when files are uploaded |

Expected Response Format

Your API must return a JSON response with at minimum a message field:

Minimal Response

{
  "message": "This is the AI assistant's response"
}

Full Response (Optional Fields)

{
  "message": "This is the AI assistant's response",
  "id": "msg-response-123",
  "timestamp": 1234567890,
  "role": "assistant",
  "attachments": [
    {
      "id": "att-1",
      "type": "image",
      "url": "https://cdn.example.com/image.jpg",
      "name": "result.jpg",
      "size": 12345,
      "mimeType": "image/jpeg"
    }
  ],
  "metadata": {
    "model": "gpt-4",
    "confidence": 0.95
  }
}

Response Fields

| Field | Type | Required | Description | |-------|------|----------|-------------| | message | string | Yes | The assistant's response text | | id | string | No | Message ID (auto-generated if omitted) | | timestamp | number | No | Unix timestamp in ms (auto-generated if omitted) | | role | string | No | Message role, defaults to "assistant" | | attachments | array | No | Files/media to display with response | | metadata | object | No | Additional data to store with message |

Note: If your response includes metadata.conversation_id, the widget will automatically use this for subsequent requests in the same session. This is useful for server-managed conversation tracking.

Quick Backend Example

// Node.js/Express
app.post('/chat', async (req, res) => {
  const { message, conversationId, history } = req.body;
  
  // Your AI logic here
  const response = await yourAI.chat(message, history);
  
  res.json({
    message: response.text,
    timestamp: Date.now()
  });
});

Error Handling

Return appropriate HTTP status codes for errors:

  • 400 - Bad Request (invalid input)
  • 401 - Unauthorized (authentication failed)
  • 429 - Too Many Requests (rate limit exceeded)
  • 500 - Internal Server Error

The widget automatically retries failed requests (500, 429) with exponential backoff.

📖 For complete API documentation with more examples, see docs/API.md

Markdown Support

The chat widget automatically renders markdown in AI responses, supporting:

  • Bold text with **text** or __text__
  • Italic text with *text* or _text_
  • Lists (ordered and unordered)
  • Inline code with backticks
  • Code blocks with triple backticks
  • Links with [text](url)
  • Headings with #, ##, ###
  • Blockquotes with >

Your AI responses can include markdown formatting and it will be rendered beautifully:

{
  "message": "**Here's the pricing:**\n\n* Free: $0\n* Standard: $200\n* Premium: $350\n\nVisit [our website](https://example.com) for details."
}

This will display with proper formatting, bold text, bullet points, and clickable links.

Configuration

Full Configuration Example

<AiChatWidget
  // Required
  apiEndpoint="https://your-api.com/chat"
  
  // Position
  position="bottom-right" // 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'
  
  // Branding
  branding={{
    name: "Support Bot",
    companyName: "Your Company",
    logoUrl: "https://your-cdn.com/logo.png",
    tagline: "We're here to help!"
  }}
  
  // Theme
  theme={{
    primaryColor: "#3b82f6",
    headerBackground: "#1e40af",
    headerTextColor: "#ffffff",
    userBubbleColor: "#3b82f6",
    botBubbleColor: "#f3f4f6",
    userTextColor: "#ffffff",
    botTextColor: "#1f2937",
    borderRadius: "0.75rem"
  }}
  
  // Features
  features={{
    enableImageUpload: true,
    enableAudioUpload: true,
    enableVideoUpload: true,
    enableFileUpload: false,
    enableTypingIndicator: true
  }}
  
  // File Constraints
  fileConstraints={{
    maxFileSize: 10 * 1024 * 1024, // 10MB
    maxImageSize: 5 * 1024 * 1024,  // 5MB
    maxAudioSize: 10 * 1024 * 1024, // 10MB
    maxVideoSize: 50 * 1024 * 1024, // 50MB
    allowedImageTypes: ['image/jpeg', 'image/png', 'image/gif'],
    allowedAudioTypes: ['audio/mpeg', 'audio/wav', 'audio/webm'],
    allowedVideoTypes: ['video/mp4', 'video/webm']
  }}
  
  // Session Management
  sessionId="user-123"
  conversationId="conv-456"
  persistConversation={true}
  
  // API Configuration
  headers={{
    'Authorization': 'Bearer YOUR_TOKEN',
    'X-Custom-Header': 'value'
  }}
  retryAttempts={3}
  retryDelay={1000}
  
  // Callbacks
  onMessageSent={(message) => console.log('Sent:', message)}
  onMessageReceived={(message) => console.log('Received:', message)}
  onError={(error) => console.error('Error:', error)}
  onStatusChange={(status) => console.log('Status:', status)}
/>

Development

Build

npm run build

Outputs to dist/ with both ESM and UMD formats.

Testing

# Run tests once
npm test

# Watch mode
npm run test:watch

Dev Server

npm run dev

Project Structure

src/
├── components/
│   └── ChatBot.tsx          # Main React component
├── hooks/
│   └── useChat.ts           # Chat state management hook
├── types/
│   └── index.ts             # TypeScript type definitions
├── __tests__/
│   ├── ChatBot.test.tsx     # Component tests
│   └── useChat.test.ts      # Hook tests
└── index.ts                 # Library entry point

Next Steps

  1. Install dependencies: npm install
  2. Run tests: npm test
  3. Build library: npm run build
  4. Use in your project or publish to npm

License

ISC

API Props Reference

AiChatWidget Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | apiEndpoint | string | Yes | - | Your backend API endpoint | | apiBase | string | No | - | EchoMind API base URL (e.g., http://localhost:3030/api) | | projectId | string | No | - | EchoMind project UUID | | userId | string | No | - | Unique identifier for end user (for chat history) | | position | string | No | 'bottom-right' | Widget position on screen | | branding | BrandingConfig | No | - | Branding customization | | theme | ChatWidgetTheme | No | - | Color and style customization | | launcher | LauncherConfig | No | - | Launcher button customization | | features | FeaturesConfig | No | - | Feature toggles | | fileConstraints | FileConstraints | No | - | File upload limits | | sessionId | string | No | - | User session identifier | | conversationId | string | No | auto-generated | Conversation identifier | | persistConversation | boolean | No | false | Save conversation to localStorage | | headers | object | No | - | Custom HTTP headers | | retryAttempts | number | No | 3 | Number of retry attempts | | retryDelay | number | No | 1000 | Initial retry delay (ms) | | onMessageSent | function | No | - | Callback when user sends message | | onMessageReceived | function | No | - | Callback when bot responds | | onError | function | No | - | Callback on error | | onStatusChange | function | No | - | Callback on status change |

useChat Hook

For advanced use cases, you can use the useChat hook directly:

import { useChat } from 'ai-chatbot'

function CustomChat() {
  const {
    messages,
    isLoading,
    error,
    conversationId,
    sendMessage,
    clearHistory,
    stopGeneration
  } = useChat({
    apiEndpoint: 'https://your-api.com/chat'
  })

  return (
    <div>
      {messages.map(msg => (
        <div key={msg.id}>{msg.content}</div>
      ))}
      <button onClick={() => sendMessage('Hello')}>
        Send
      </button>
    </div>
  )
}

TypeScript Support

The library is written in TypeScript with full type safety using enums:

import { 
  AiChatWidget,
  MessageRole,
  ChatStatus,
  AttachmentType,
  LauncherPosition
} from 'ai-chatbot'

import type { 
  ChatMessage, 
  ChatWidgetConfig, 
  BrandingConfig, 
  ChatWidgetTheme,
  FeaturesConfig,
  FileConstraints,
  ChatApiError
} from 'ai-chatbot'

// Use enums for type safety
const status: ChatStatus = ChatStatus.CONNECTED
const role: MessageRole = MessageRole.ASSISTANT

Development

Build

npm run build

Outputs to dist/ with both ESM and UMD formats plus TypeScript declarations.

Testing

# Run tests once
npm test

# Watch mode
npm run test:watch

Dev Server

npm run dev

Architecture

Built with a layered architecture for maintainability and scalability:

src/
├── components/           # Presentation Layer
│   ├── ChatHeader.tsx
│   ├── ChatInput.tsx
│   ├── ChatLauncher.tsx
│   ├── ChatMessage.tsx
│   ├── ChatMessages.tsx
│   ├── ChatWindow.tsx
│   ├── TypingIndicator.tsx
│   └── index.tsx        # Main AiChatWidget component
├── hooks/               # Business Logic Layer
│   ├── useChat.ts       # State management with service integration
│   └── useLocalStorage.ts
├── services/            # Service Layer (NEW in v2.0)
│   └── chatApi.service.ts  # API communication with retry logic
├── utils/               # Utility Layer
│   ├── config.validator.ts # Configuration validation (NEW)
│   ├── logger.ts           # Structured logging (NEW)
│   ├── fileValidation.ts
│   └── sanitize.ts
├── constants/           # Constants Layer (NEW in v2.0)
│   └── index.ts         # All constants and defaults
├── types/               # Type Layer
│   └── index.ts         # TypeScript definitions with enums
├── styles/
│   └── defaultTheme.ts
└── index.ts             # Library entry point

See ARCHITECTURE.md for detailed architecture documentation.

What's New in v2.0.0

Breaking Changes

  • Component renamed from ChatBot to AiChatWidget
  • String literals replaced with type-safe enums (MessageRole, ChatStatus, etc.)
  • New service layer architecture

New Features

  • ✅ Service layer for API communication
  • ✅ Configuration validation
  • ✅ Structured logging with logger utility
  • ✅ Typed errors with ChatApiError
  • ✅ Enhanced retry logic with exponential backoff
  • ✅ Better error handling throughout

Migration from v1.x

// Before (v1.x)
import { ChatBot } from 'ai-chatbot'
<ChatBot apiEndpoint="..." />

// After (v2.0)
import { AiChatWidget } from 'ai-chatbot'
<AiChatWidget apiEndpoint="..." />

See ARCHITECTURE.md for complete migration guide.

Documentation

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Contributing

Contributions are welcome! Please follow the architecture guidelines in ARCHITECTURE.md.

License

ISC

Support

For issues and questions, please open an issue on GitHub.