logo
0
0
WeChat Login

Kira Chat

A feature-rich, beautifully crafted React AI chat component library

npm version npm downloads license React TypeScript Vite TailwindCSS

Kira Chat is a React AI chat component library that provides a ready-to-use chat interface. It supports streaming output, Markdown rendering, math formulas, code highlighting, and tool call visualization. Built on an adapter pattern, you can connect any AI backend by implementing a single function. The built-in CSS Token theme system lets you fully customize the look via variables, with support for light/dark/auto modes.

English | 简体中文


Features

  • Streaming Output -- Typing animation for a native AI conversation experience
  • Full Markdown -- GFM tables, task lists, strikethrough
  • Math Formulas -- KaTeX-based LaTeX rendering (inline & block)
  • Code Highlighting -- Prism.js-powered, 40+ languages, one-click copy
  • Tool Call Visualization -- Execution process cards with custom renderers
  • Conversation Management -- Pin, rename, search, delete
  • CSS Token Theming -- Fully driven by CSS variables, no style code changes needed
  • Dark Mode -- Built-in light / dark / auto, follows system preference
  • Adapter Pattern -- Connect any AI backend by implementing a single function
  • TypeScript -- Full type exports
  • Zero-config Integration -- Import and use out of the box

Quick Start

Install

npm install @hakurei/kira-chat

Import Styles

import '@hakurei/kira-chat/styles'

Minimal Usage

import { AIChat } from '@hakurei/kira-chat'
import type { AIAdapter } from '@hakurei/kira-chat'

const adapter: AIAdapter = async ({ messages, onChunk, onComplete, signal }) => {
  const res = await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${import.meta.env.VITE_OPENAI_KEY}`,
    },
    body: JSON.stringify({
      model: 'gpt-4o',
      stream: true,
      messages: messages.map((m) => ({ role: m.role, content: m.content })),
    }),
    signal,
  })

  const reader = res.body!.getReader()
  const decoder = new TextDecoder()

  while (true) {
    const { done, value } = await reader.read()
    if (done) break
    const text = decoder.decode(value)
    for (const line of text.split('\n')) {
      if (!line.startsWith('data: ') || line === 'data: [DONE]') continue
      try {
        const json = JSON.parse(line.slice(6))
        const chunk = json.choices?.[0]?.delta?.content
        if (chunk) onChunk?.(chunk)
      } catch {}
    }
  }

  onComplete?.({ id: '', role: 'assistant', content: '', status: 'done', createdAt: Date.now() })
}

export default function App() {
  return (
    <AIChat
      adapter={adapter}
      theme={{ preset: 'light' }}
      height="100vh"
    />
  )
}

Theming

CSS Token Structure

All colors are controlled via CSS custom properties in RGB triplet format (without alpha), designed to work seamlessly with Tailwind's /opacity syntax.

[data-hk-theme="light"] {
  --hk-primary: 99 102 241;        /* indigo-500 */
  --hk-primary-foreground: 255 255 255;
  --hk-background: 255 255 255;
  --hk-foreground: 15 23 42;
  --hk-surface: 248 250 252;
  --hk-border: 226 232 240;
  /* ... */
}

Customize via theme prop

<AIChat
  theme={{
    preset: 'light',       // 'light' | 'dark' | 'auto'
    light: {
      primary: '168 85 247',         // purple-500
      primaryForeground: '255 255 255',
      accent: '217 70 239',
      radiusLg: '20px',              // larger border radius
    },
    dark: {
      primary: '192 132 252',        // purple-400
    },
  }}
/>

Token Reference

TokenCSS VariableDescription
primary--hk-primaryPrimary color (buttons, links, etc.)
primaryForeground--hk-primary-foregroundPrimary foreground (white/black)
background--hk-backgroundRoot background
surface--hk-surfaceCard/sidebar background
surfaceElevated--hk-surface-elevatedElevated/highlight background
foreground--hk-foregroundPrimary text color
border--hk-borderBorder color
muted--hk-mutedSecondary background
mutedForeground--hk-muted-foregroundSecondary text color
destructive--hk-destructiveDanger/error color
success--hk-successSuccess color
radiusSm/Md/Lg/Xl--hk-radius-*Border radius sizes
fontSans/Mono--hk-font-*Font stacks

Component API

<AIChat />

PropTypeDefaultDescription
adapterAIAdapter--AI request adapter (required)
conversationsConversation[]--Controlled conversation list
activeConversationIdstring--Active conversation ID
toolsToolDefinition[]--Tool definitions
themeThemeConfig{ preset: 'light' }Theme configuration
showSidebarbooleantrueShow sidebar
allowAttachmentsbooleanfalseAllow file attachments
placeholderstring--Input placeholder text
welcomeTitlestring--Welcome page title
heightstring | number'100%'Container height
onConversationCreate(c: Conversation) => void--Conversation create callback
onConversationSelect(id: string) => void--Conversation select callback
onMessageSend(msg, cid) => void--Message send callback

AIAdapter Interface

type AIAdapter = (options: SendMessageOptions) => Promise<void>

interface SendMessageOptions {
  conversationId: string
  messages: Message[]          // message history
  onChunk?: (chunk: string) => void      // streaming text chunk
  onToolCall?: (toolCall: ToolCall) => void  // tool call
  onComplete?: (message: Message) => void    // completion
  onError?: (error: Error) => void           // error
  signal?: AbortSignal                       // abort signal
}

Tool Call ToolDefinition

interface ToolDefinition {
  name: string
  description?: string
  parameters?: Record<string, unknown>  // JSON Schema
  icon?: React.ReactNode                // custom icon
  renderCall?: (call: ToolCall) => React.ReactNode      // custom input renderer
  renderResult?: (result: ToolResult, call?: ToolCall) => React.ReactNode  // custom result renderer
}

Standalone Components

All sub-components can be imported individually:

import {
  ChatWindow,
  ChatInput,
  MessageBubble,
  ToolCallCard,
  ConversationList,
  MarkdownRenderer,
  ThemeProvider,
} from '@hakurei/kira-chat'

<ThemeProvider /> Standalone Usage

<ThemeProvider theme={{ preset: 'dark', dark: { primary: '56 189 248' } }}>
  <YourApp />
</ThemeProvider>

State Management

The component includes a built-in Zustand store, accessible via the useChatStore hook:

import { useChatStore } from '@hakurei/kira-chat'

function MyComponent() {
  const {
    conversations,
    activeConversationId,
    createConversation,
    deleteConversation,
    addMessage,
    stopStreaming,
  } = useChatStore()

  // ...
}

Development

git clone https://github.com/hakurei/kira-chat.git
cd kira-chat
npm install
npm run dev    # Start demo playground

Build the library:

npm run build  # Output to dist/

Contributing

Issues and Pull Requests are welcome!


License

MIT © hakurei

About

Kira Chat 是一个功能丰富的 React AI 聊天组件库。它提供开箱即用的聊天界面,支持流式输出、Markdown 渲染、数学公式、代码高亮和工具调用可视化。基于适配器模式,只需实现一个函数即可接入任何 AI 后端(OpenAI、Ollama、vLLM 等)。内置 CSS Token 主题系统,通过变量即可完全定制外观,支持亮色/暗色/跟随系统三种模式。

500.00 KiB
0 forks0 stars2 branches1 TagREADMEMIT license
Language
TypeScript87.5%
CSS8.4%
JavaScript4.1%