A self-hosted, multi-provider AI chatbot built with React and Hono. Users bring their own provider credentials and can stream responses, opt into web research or provider reasoning, preserve long conversations with rolling summaries and deep-context compression, and inspect response metadata including estimated cost and prompt cache hits.
Release status:
v0.3.4is a public beta. The fully verified backend target is one long-lived Node.js process. Static frontend deployment is supported on hosts that can apply SPA rewrites and security headers. Serverless adapters are not included in this release.
- OpenAI Chat Completions-compatible, native Anthropic Messages, and native Gemini
generateContentprotocols - Custom endpoints for gateways that implement one of those wire protocols
- Per-user provider credentials encrypted at rest with AES-256-GCM
- Portable bcrypt password hashing with cost factor 12
- Signed HttpOnly cookie sessions, exact-origin checks, and process-local rate limits
- In-chat provider setup guidance when no active API credential is configured
- Web search and reasoning disabled by default for every message
- Estimated token-aware context selection, rolling AI-generated summaries, and hierarchical deep-context compression
- AI-generated first-message titles with a deterministic local fallback
- Response receipts containing provider, model, endpoint host, latency, reported token usage (including prompt cache hits), estimated cost, context estimates, and candidate web sources
- Prompt cache tracking for Anthropic (
cache_control), OpenAI (auto-cache), and Gemini (cachedContentTokenCount) - Provider-aware token estimation and per-model cost estimation stored per receipt
- Markdown export and a responsive, keyboard-accessible chat interface with light and dark modes
- Light mode (clean warm white) and OLED dark mode, switchable via a sidebar toggle or OS preference; theme persists across sessions
- SQLite by default, or PostgreSQL, MySQL, and MariaDB through Kysely
- Brave Search API and SearXNG JSON support with a bounded DuckDuckGo/Bing HTML fallback
- Vendor-neutral static frontend and Node.js backend
React SPA -> Hono API -> SQLite / PostgreSQL / MySQL / MariaDB
|-> OpenAI-compatible Chat Completions
|-> Anthropic Messages
|-> Gemini generateContent
|-> public web search and page extraction
The Hono application in backend/src/app.ts is separated from the Node listener in backend/src/index.ts. It remains a Node-targeted application because the provider SDKs, database drivers, and streaming lifecycle use Node APIs. See Architecture for the request flow, storage model, failure behavior, and runtime boundaries.
Use Node.js 24 LTS or a newer supported LTS release.
-
Install dependencies:
npm ci npm ci --prefix backend npm ci --prefix frontend
-
Copy
backend/.env.exampletobackend/.env. -
Run the following command twice and assign different outputs to
JWT_SECRETandCREDENTIAL_ENCRYPTION_KEY:node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"
-
Keep
DATABASE_URL=empty for local SQLite. -
Run
npm run devfrombackendandfrontendin separate terminals. -
Open
http://localhost:5173, register an account, and configure a provider.
The Vite development server proxies /api to http://localhost:3000. No frontend env file is needed for this local setup. Copy frontend/.env.example only when the browser must call a different backend origin or the static build needs additional CSP origins.
Choose a provider by wire protocol, not by the model brand exposed by a gateway:
| Setting | Required endpoint behavior |
|---|---|
| OpenAI Compatible | OpenAI-style POST /chat/completions, including streaming chat-completion chunks |
| Claude | Native Anthropic Messages API semantics |
| Gemini | Native Gemini generateContent and streamGenerateContent semantics |
Use OpenAI Compatible for a gateway serving Claude or Gemini models through an OpenAI-style interface. OpenAI itself can be configured with https://api.openai.com/v1. Custom Claude and Gemini endpoints must implement their selected native protocol; a model name alone does not make an endpoint compatible.
Reasoning controls are best-effort and provider/model dependent. The OpenAI-compatible adapter retries without modern reasoning parameters after a 400 or 422, so a compatible text endpoint can still work while exposing no reasoning text. Provider validation sends a real eight-token completion and may consume provider quota. The first message can trigger a separate title completion, and long conversations can trigger separate summary completions.
Protocol references: OpenAI Chat Completions, Anthropic Messages, and Gemini content generation.
- Frontend: publish
frontend/distto Netlify, Cloudflare Pages, or another static host. SetVITE_API_BASE_URLat build time when the API is on another origin. - Backend: run the compiled Node.js process. An empty
DATABASE_URLusesbackend/database/chatbot.db; a supported database URL selects a remote database. - Serverless: the app export can be integrated with a Node-compatible adapter, but this repository does not provide or verify one. The platform must support streaming responses, remote database connections, and replacements for process-local coordination when scaling horizontally.
Production requires FRONTEND_URL, JWT_SECRET, CREDENTIAL_ENCRYPTION_KEY, and the DATABASE_URL variable. DATABASE_URL must exist even when its value is empty. See Deployment before publishing.
npm run verifyThis runs Biome checks, backend unit and SQLite migration integration tests, production builds, and a Node HTTP smoke test. The smoke test covers authentication, exact-origin enforcement, quotas, recent-history loading, credential redaction/deletion, and receipt loading. It does not call real AI/search providers, run browser automation, test every remote database driver, or replace dependency and infrastructure security scans.
Use npm --prefix backend run test:database against a disposable or newly provisioned remote database before production traffic. The script creates and deletes its own test user, but it still runs the current migrations against that database.
Repository-authored source code, documentation, and assets are licensed under the MIT License, unless a file states otherwise. Third-party dependencies keep their own licenses.