A beautiful web UI for the Claude Code & Codex CLIs
bun install -g kanna-codeIf Bun isn't installed, install it first:
curl -fsSL https://bun.sh/install | bashThen run from any project directory:
kannaThat's it. Kanna opens in your browser at localhost:3210.
- Multi-provider support — switch between Claude and Codex (OpenAI) from the chat input, with per-provider model selection, reasoning effort controls, and Codex fast mode
- Project-first sidebar — chats grouped under projects, with live status indicators (idle, running, waiting, failed)
- Drag-and-drop project ordering — reorder project groups in the sidebar with persistent ordering
- Local project discovery — auto-discovers projects from both Claude and Codex local history
- Rich transcript rendering — hydrated tool calls, collapsible tool groups, plan mode dialogs, and interactive prompts with full result display
- Quick responses — lightweight structured queries (e.g. title generation) via Haiku with automatic Codex fallback
- Plan mode — review and approve agent plans before execution
- Persistent local history — refresh-safe routes backed by JSONL event logs and compacted snapshots
- Auto-generated titles — chat titles generated in the background via Claude Haiku
- Session resumption — resume agent sessions with full context preservation
- WebSocket-driven — real-time subscription model with reactive state broadcasting
Browser (React + Zustand)
↕ WebSocket
Bun Server (HTTP + WS)
├── WSRouter ─── subscription & command routing
├── AgentCoordinator ─── multi-provider turn management
├── ProviderCatalog ─── provider/model/effort normalization
├── QuickResponseAdapter ─── structured queries with provider fallback
├── EventStore ─── JSONL persistence + snapshot compaction
└── ReadModels ─── derived views (sidebar, chat, projects)
↕ stdio
Claude Agent SDK / Codex App Server (local processes)
↕
Local File System (~/.kanna/data/, project dirs)
Key patterns: Event sourcing for all state mutations. CQRS with separate write (event log) and read (derived snapshots) paths. Reactive broadcasting — subscribers get pushed fresh snapshots on every state change. Multi-provider agent coordination with tool gating for user-approval flows. Provider-agnostic transcript hydration for unified rendering.
- Bun v1.3.5+
- A working Claude Code environment
- (Optional) Codex CLI for Codex provider support
Embedded terminal support uses Bun's native PTY APIs and currently works on macOS/Linux.
Install Kanna globally:
bun install -g kanna-codeIf Bun isn't installed, install it first:
curl -fsSL https://bun.sh/install | bashOr clone and build from source:
git clone https://github.com/jakemor/kanna.git
cd kanna
bun install
bun run buildkanna # start with defaults
kanna --port 4000 # custom port
kanna --no-open # don't open browserDefault URL: http://localhost:3210
bun run devOr run client and server separately:
bun run dev:client # http://localhost:5174
bun run dev:server # http://localhost:3211| Command | Description |
|---|---|
bun run build |
Build for production |
bun run check |
Typecheck + build |
bun run dev |
Run client + server together |
bun run dev:client |
Vite dev server only |
bun run dev:server |
Bun backend only |
bun run start |
Start production server |
src/
├── client/ React UI layer
│ ├── app/ App router, pages, central state hook, socket client
│ ├── components/ Messages, chat chrome, dialogs, buttons, inputs
│ ├── hooks/ Theme, standalone mode detection
│ ├── stores/ Zustand stores (chat input, preferences, project order)
│ └── lib/ Formatters, path utils, transcript parsing
├── server/ Bun backend
│ ├── cli.ts CLI entry point & browser launcher
│ ├── server.ts HTTP/WS server setup & static serving
│ ├── agent.ts AgentCoordinator (multi-provider turn management)
│ ├── codex-app-server.ts Codex App Server JSON-RPC client
│ ├── provider-catalog.ts Provider/model/effort normalization
│ ├── quick-response.ts Structured queries with provider fallback
│ ├── ws-router.ts WebSocket message routing & subscriptions
│ ├── event-store.ts JSONL persistence, replay & compaction
│ ├── discovery.ts Auto-discover projects from Claude and Codex local state
│ ├── read-models.ts Derive view models from event state
│ └── events.ts Event type definitions
└── shared/ Shared between client & server
├── types.ts Core data types, provider catalog, transcript entries
├── tools.ts Tool call normalization and hydration
├── protocol.ts WebSocket message protocol
├── ports.ts Port configuration
└── branding.ts App name, data directory paths
All state is stored locally at ~/.kanna/data/:
| File | Purpose |
|---|---|
projects.jsonl |
Project open/remove events |
chats.jsonl |
Chat create/rename/delete events |
messages.jsonl |
Transcript message entries |
turns.jsonl |
Agent turn start/finish/cancel events |
snapshot.json |
Compacted state snapshot for fast startup |
Event logs are append-only JSONL. On startup, Kanna replays the log tail after the last snapshot, then compacts if the logs exceed 2 MB.