@geepers/chat
v2.1.1
Published
Multi-provider LLM chat. Drop-in widget OR full app: npx @geepers/chat spins up a server with 10 providers. Streaming, history, markdown. No framework required.
Maintainers
Readme
@geepers/chat
Full-featured chat UI for multi-provider LLM APIs. Drop a ChatUI instance into any container and get streaming chat, conversation history, markdown rendering, and provider switching. No framework required.
Supports 9 providers out of the box: xAI, Anthropic, OpenAI, Cohere, Mistral, Perplexity, HuggingFace, Google Gemini, and Ollama.
Built from the Slate/Camina implementation in IO Suite.
Install
npm install @geepers/chatUsage
import ChatUI from '@geepers/chat';
const chat = new ChatUI('#app', {
gateway: 'https://api.dr.eamer.dev/v1',
apiKey: 'sk_...',
provider: 'anthropic',
welcomeHints: [
{ label: 'How do LLMs work?', prompt: 'Explain how LLMs work in plain language.' },
],
});That's it. The element at #app becomes a full chat interface with sidebar history, streaming responses, and a mobile-responsive layout.
Headless mode
Use ChatCore without any DOM if you want to build your own UI on top:
import { ChatCore } from '@geepers/chat';
const core = new ChatCore({
gateway: 'https://api.dr.eamer.dev/v1',
apiKey: 'sk_...',
provider: 'xai',
});
core.on('stream-chunk', (e) => {
process.stdout.write(e.chunk);
});
await core.send('Hello!');Script tag (no build step)
<div id="app" style="height: 600px;"></div>
<script src="https://unpkg.com/@geepers/chat/dist/index.iife.global.js"></script>
<script>
new GChat.ChatUI('#app', { apiKey: 'sk_...' });
</script>Config
interface ChatConfig {
gateway?: string; // API base URL (default: https://api.dr.eamer.dev/v1)
apiKey?: string; // Falls back to localStorage 'api_key' if not set
provider?: Provider; // Starting provider (default: 'xai')
model?: string; // Override the default model for the provider
systemPrompt?: string; // Prepended to every conversation
theme?: 'light' | 'dark' | 'auto'; // Default: 'auto'
welcomeHints?: WelcomeHint[]; // Hint chips on the welcome screen
storageKey?: string; // localStorage key prefix (namespace multiple instances)
// Callbacks
onMessage?: (msg: Message) => void;
onError?: (err: Error) => void;
onStreamStart?: (messageId: string) => void;
onStreamEnd?: (msg: Message) => void;
}ChatUI methods
| Method | Description |
|--------|-------------|
| send(text) | Send a message programmatically |
| stop() | Abort the current stream |
| focus() | Focus the message input |
| setProvider(p) | Switch provider (updates UI) |
| setSystemPrompt(s) | Update system prompt (updates UI) |
| newConversation() | Clear history and start fresh |
| destroy() | Remove the UI from the DOM |
| chatCore | Access the underlying ChatCore directly |
Providers
| Key | Model | Label |
|-----|-------|-------|
| xai | grok-4 | xAI Grok 4 |
| anthropic | claude-sonnet-4-6 | Claude Sonnet 4.6 |
| openai | gpt-5.4 | OpenAI GPT-5.4 |
| cohere | command-r-plus-08-2024 | Cohere Command R+ |
| mistral | mistral-large-latest | Mistral Large |
| perplexity | sonar-pro | Perplexity Sonar Pro |
| huggingface | Qwen/Qwen3.5-9B | HuggingFace Qwen 3.5 |
| gemini | gemini-2.5-flash | Google Gemini 2.5 |
| ollama | llama3.2:3b | Ollama (Local) |
CSS customization
The UI uses CSS custom properties scoped under .gchat-root. Override any token:
.gchat-root {
--gchat-accent: #e11d48; /* primary color */
--gchat-sidebar-w: 300px; /* sidebar width */
--gchat-font: 'Inter', sans-serif;
}License
MIT — Luke Steuber
