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

chat-bubble-ai

v1.1.3

Published

A customizable AI chat bubble component for React

Readme

chat-bubble-ai

A highly customizable, zero-dependency-on-icon-fonts React chat bubble component designed for seamless integration with AI streaming agents.

Features

  • 💬 Streaming Support — Built-in Server-Sent Events (SSE) streaming for real-time AI responses.
  • 🎨 Fully Themeable — CSS variables, dark mode, custom message bubble styles, and fonts.
  • 📦 Zero Font Dependencies — All icons are inline SVGs; no Material Symbols or icon font required.
  • 🖼️ HTML Rendering — Assistant messages support rich HTML (cards, images, lists, etc.).
  • 📱 Responsive — Works on desktop and mobile out of the box.
  • 🧩 Multiple Modes — Use as a full-page chat, a floating bubble, or an embedded iframe widget.
  • 🔌 Easy Integration — One config object controls everything: URL, auth, theme, header, and input.

Installation

npm install chat-bubble-ai
# or
yarn add chat-bubble-ai

Usage

1. Full-page / Embedded Chat

Wrap ChatBubbleComponent in a ChatBubbleProvider and place it inside any sized container.

import {
  ChatBubbleProvider,
  ChatBubbleComponent,
} from 'chat-bubble-ai';
import type { ChatBubbleConfig } from 'chat-bubble-ai';

const config: ChatBubbleConfig = {
  url: 'https://api.your-service.com/stream', // SSE streaming endpoint
  token: 'your-api-key',                      // Optional auth token
  darkMode: false,
  header: {
    title: 'AI Assistant',
    subtitle: 'Ask me anything',
    avatar: {
      type: 'image',
      src: 'https://example.com/avatar.webp',
    },
  },
  input: {
    placeholder: 'Type your message...',
    showSendButton: true,
    showVoice: false,
  },
};

export default function App() {
  return (
    <ChatBubbleProvider>
      <div style={{ height: '600px', width: '400px' }}>
        <ChatBubbleComponent config={config} />
      </div>
    </ChatBubbleProvider>
  );
}

2. Floating Chat Widget

A self-contained floating button that expands into a chat panel — no provider needed.

import { FloatingChatWidget } from 'chat-bubble-ai';

export default function App() {
  return (
    <FloatingChatWidget
      config={{
        url: 'https://api.your-service.com/stream',
        token: 'your-api-key',
        header: {
          title: 'Support Bot',
        },
        launcher: {
          color: '#137fec',        // Button background color
          // imageUrl: '/bot.png', // Optional custom launcher image
        },
      }}
    />
  );
}

3. Embedded Widget (Iframe-friendly)

Designed for embedding inside an iframe. Notifies the parent window via postMessage when the chat opens or closes.

import { EmbeddedChatWidget } from 'chat-bubble-ai';

export default function App() {
  return (
    <EmbeddedChatWidget
      config={{
        url: 'https://api.your-service.com/stream',
        token: 'your-api-key',
      }}
      showNotificationBadge={true}
      notificationCount={3}
    />
  );
}

Configuration Reference

ChatBubbleConfig

| Property | Type | Default | Description | | -------------- | ------------------ | ----------- | -------------------------------------------------------- | | url | string | — | Required. SSE streaming endpoint URL. | | token | string | — | Optional API key sent as x-api-key header. | | darkMode | boolean | true | Enable dark mode on load. | | height | string | '100vh' | Container height (CSS value). | | maxWidth | string | '100%' | Container max-width (CSS value). | | theme | ChatTheme | — | Customize colors, fonts, and message bubble styles. | | header | ChatHeaderConfig | — | Title, subtitle, avatar, and action buttons. | | input | ChatInputConfig | — | Placeholder, send button, emoji, voice, and more. | | launcher | LauncherConfig | — | Floating button color, icon, and notification animation. | | notification | NotificationConfig | — | Notification bubble message, interval, duration, and dot styling. | | initialMessage | string | — | Initial greeting message shown by the assistant when chat opens. | | style | React.CSSProperties | — | Additional inline styles for the root container. |


NotificationConfig

| Property | Type | Default | Description | | ----------------- | ----------------------- | ------- | ------------------------------------------------ | | message | string | — | Required. Text to show in the notification bubble. | | interval | number | 30000 | Time in ms between notification appearances. | | duration | number | 5000 | Time in ms the notification stays visible. | | showImmediately | boolean | true | Show the notification right away on mount. Set to false to wait for the first interval before appearing. | | dot | NotificationDotConfig | — | Customization for the red notification dot. |

NotificationDotConfig

| Property | Type | Default | Description | | ------------------- | --------- | ----------- | --------------------------------------------------------------------------- | | show | boolean | true | Show or hide the dot entirely. | | color | string | '#ef4444' | Dot color (hex, rgb, etc.). | | size | number | 10 | Dot diameter in pixels. | | ringColor | string | color | Color of the animating ripple ring. | | animationDuration | number | 1.2 | Animation cycle duration in seconds. | | animationScale | number | 2.2 | Max scale the ring reaches during animation. | | bubblePosition | object | { side: 'left', offset: '10px' } | Position of the dot inside the notification message bubble. |


AvatarConfig

| Property | Type | Description | | ----------- | --------------------------- | ------------------------------------------------ | | type | 'image' \| 'icon' \| 'text' | How to render the avatar. | | src | string | Image URL (when type: 'image'). | | icon | React.ReactNode \| string | SVG component or string (when type: 'icon'). | | text | string | Initials or short text (when type: 'text'). | | size | 'sm' \| 'md' \| 'lg' | Avatar size. Default: 'md'. | | backgroundColor | string | CSS color for the avatar background. | | textColor | string | CSS color for text/icon inside the avatar. |


Theming (ChatTheme)

Override colors and message bubble styles via the theme prop:

const config: ChatBubbleConfig = {
  // ...
  theme: {
    cssVariables: {
      colorPrimary: '#137fec',
      colorBackgroundLight: '#f8fafc',
      colorSurfaceLight: '#ffffff',
      colorBorderLight: '#e2e8f0',
    },
    messageBubbles: {
      user: {
        background: '#137fec',
        textColor: '#ffffff',
      },
      assistant: {
        background: '#f1f5f9',
        textColor: '#1e293b',
      },
    },
  },
};

Available CSS Variables

| Variable | Description | | ------------------------- | ---------------------------------- | | colorPrimary | Primary accent color | | colorPrimaryHover | Primary color on hover | | colorBackgroundLight | Chat area background (light mode) | | colorBackgroundDark | Chat area background (dark mode) | | colorSurfaceLight | Header/input surface (light mode) | | colorSurfaceDark | Header/input surface (dark mode) | | colorBorderLight | Border color (light mode) | | colorBorderDark | Border color (dark mode) | | colorTextSecondary | Secondary text color | | fontSans | Font family override |


⚡ Performance Tip

To avoid unexpected re-renders or state resets (e.g., chat history clearing on update), ensure the config object reference remains stable.

Option 1: Define outside the component (Best for static configs)

const chatConfig = { /* ... */ };

function App() {
  return <FloatingChatWidget config={chatConfig} />;
}

Option 2: Use useMemo (Best for dynamic configs)

function App() {
  const chatConfig = useMemo(() => ({ /* ... */ }), [dep]);
  return <FloatingChatWidget config={chatConfig} />;
}

API Requirements

The component expects a Server-Sent Events (SSE) streaming response from the configured url.

  • Method: POST
  • Headers:
    • Content-Type: application/json
    • x-api-key: [token] (if token is provided)
  • Body:
    {
      "message": "User's message text",
      "conversationId": "uuid-v4-string"
    }
  • Response: A stream of text chunks (SSE format), which are appended to the assistant message in real time.

HTML Rendering

Assistant messages support rich HTML. Return HTML directly from your API — the component renders it with dangerouslySetInnerHTML:

<div>
  <h3>Hotel Paradise</h3>
  <img src="https://example.com/hotel.jpg" style="width:100%;border-radius:8px" />
  <p>Price: <strong>$200/night</strong></p>
</div>

Note: Send raw HTML tags — do not HTML-encode them (e.g., send <div>, not &lt;div&gt;).


Changelog

v0.1.9

  • Added initialMessage property to ChatBubbleConfig for custom welcome messages.
  • Added NotificationDotConfig to supported granular customization of the notification dot (color, size, animation, position).
  • Improved notification bubble positioning on mobile devices to prevent overflow.
  • Refactored ChatBubbleProvider to support message injection from config.

v0.1.7

  • Replaced all Material Symbols icon font references with inline SVG components.
  • Replaced all Tailwind CSS utility classes with inline styles for zero-CSS-framework dependency at runtime.
  • Fixed Avatar size mapping (was passing Tailwind class strings to style.width/height).
  • Default assistant avatar now uses a configurable image URL instead of an SVG icon.
  • EmbeddedChatWidget rewritten to use inline styles (removed dependency on ChatBubble.styles.css classes).

v0.1.6

  • Added styles.css with Tailwind import to ensure CSS is bundled in dist/chat-bubble-ai.css.
  • Created icons.tsx with inline SVG components (SendIcon, CloseIcon, ChatBubbleIcon, MoodIcon, MicIcon).
  • Updated ChatBubble.types.ts to accept React.ReactNode for icon props.

License

MIT