English · 简体中文
A desktop and browser UI for Claude Code.
It does not reimplement Claude Code — it drives the real CLI through the Agent
SDK, so your settings, CLAUDE.md, MCP servers, skills, agents and hooks all
behave exactly as they do in the terminal. What it adds is everything the TUI
makes you type: a model picker that knows what each alias resolves to, permission
prompts you click, a diff view for every edit, full-text search across your
transcripts, and rewind.
A session started in a terminal shows up in the app, and a session started in the app can be resumed in a terminal. They are the same transcripts on disk.
- The
claudeCLI, installed and logged in. This app is a front-end for it, not a replacement — it cannot talk to the API on its own. Get it from claude.com/claude-code and runclaudeonce to sign in. - Windows x64 for the prebuilt installer. Running from source works anywhere Node does.
- Node.js 20+, only if you build from source.
The app finds the CLI on PATH, then in the usual install locations
(~/.local/bin, %APPDATA%\npm). If yours lives somewhere else, set
CLAUDE_CLI_PATH to its full path.
- Download
Claude Code UI Setup <version>.exefrom the Releases page. - Run it. It installs per-user under
%LOCALAPPDATA%\Programs\Claude Code UI, so there is no UAC prompt and no admin rights needed. - Launch it from the Start menu or the desktop shortcut.
The installer is ~85 MB and ~280 MB installed, most of which is Electron. It does not bundle the Claude CLI — see Requirements.
To uninstall: Settings → Apps, or Uninstall Claude Code UI.exe in the install
directory. Your transcripts live in ~/.claude and are left alone.
Not code-signed. SmartScreen will warn on first run. Choose More info → Run anyway, or build from source if you would rather not.
git clone git@github.com:hasong66/ClaudeCodeUI.git
cd ClaudeCodeUI
npm installnpm run dev # server on :8787, Vite dev server on :5183 — open localhost:5183Or as a single-port production server:
npm run build && npm start # http://localhost:8787Or as the desktop app:
npm run electron # builds the client, then opens the Electron windownpm run dist # -> release/Claude Code UI Setup <version>.exe
npm run pack # -> release/win-unpacked/ (no installer, for testing)CCUI_BUNDLE_CLI=1 npm run dist additionally bundles the Claude CLI that ships
with the Agent SDK, producing an installer that works on a machine with no Claude
Code at all. It costs ~215 MB and freezes the CLI at whatever version the build
resolved, which is why it is off by default.
Behind a proxy that cannot reach GitHub
Electron and electron-builder download their binaries from GitHub. Point them at a mirror:
export ELECTRON_MIRROR=https://registry.npmmirror.com/-/binary/electron/
export ELECTRON_BUILDER_BINARIES_MIRROR=https://registry.npmmirror.com/-/binary/electron-builder-binaries/
npm run distelectron-builder also unpacks a code-signing toolchain containing two macOS
symlinks, which Windows refuses to create without Developer Mode. If that fails,
extract it once by hand into
%LOCALAPPDATA%\electron-builder\Cache\winCodeSign\winCodeSign-2.6.0\ — the two
.dylib links it fails on are not used by a Windows build.
| Chat | Streaming responses, thinking blocks, tool calls folded into cards, Edit/Write rendered as diffs |
| Model | Filled from the CLI's own catalogue, showing what each alias resolves to (opus → claude-opus-5). Pin a specific version when you need one |
| Permissions | Approve tool calls in the UI, or switch the session to auto-accept / plan / full access |
| Sessions | Every transcript on disk, searchable full-text, resumable, deletable (to a trash directory, not rm) |
| Rewind | Restart a session from just before any message |
| Config | MCP servers, skills, agents, CLAUDE.md, permission rules, hooks, plugins and raw settings.json — all editing the same files the CLI reads |
| Terminal | A real PTY running the real TUI, for /login, /doctor and anything else that only renders there |
| Language | English / 简体中文, switchable in the sidebar |
Attachments are images only. Other files are referenced with @path, which is
better anyway — Claude reads them from disk instead of through the context.
The server binds to 127.0.0.1 and has no authentication. Anyone who reaches
it gets full tool access on your machine, with whatever permissions the session is
set to. Do not expose it to a network, and do not put it behind a reverse proxy
without adding auth of your own.
Model prose is sanitised with DOMPurify before rendering, including the streaming draft, so a half-arrived message never flashes its raw source.
browser ──/ws────► chat + control ──► Agent SDK query() ──► claude CLI (one long-lived child per session)
└─/shell─► PTY channel ──► node-pty ──────────► claude CLI (interactive TUI)
└─/api───► config routes ──► ~/.claude.json, .mcp.json, ~/.claude/{skills,agents}, settings.json, CLAUDE.md
One CLI process stays alive for the whole session rather than being respawned per
turn, which is what makes the SDK's control channel usable — setModel,
mcpServerStatus, getContextUsage and friends all need a query that still
exists. In the desktop build the server runs as a separate Node process rather
than inside Electron's main process, so the packaged app runs the same code the
tests cover.
Architecture and design notes → covers the rest: why there are two channels, how rewind actually forgets, the session-id split, and the Windows-specific traps that shaped the build.
With the server running (npm start or npm run dev:server):
npm run smoke:control # every Query control method against a live session
npm run smoke:config # agents, CLAUDE.md, permissions, hooks, plugins, search
npm run smoke:rewind # rewind really forgets; image attachments really arrive
npm run smoke:ui # mounts the real client in jsdom and drives it
npm run smoke:md # markdown rendering and sanitisation
npm run smoke:electron # the desktop shell: server child, window, shortcutsnpm run smoke:dev starts its own servers, so run it with nothing else on
:8787/:5183. Every script honours UI_ORIGIN, so the suite can be pointed at a
packaged build's server instead of the checkout.
- No auth, no multi-user; bound to localhost by design.
- Stream state lives in memory. Restarting the server clears replay buffers; transcripts on disk are unaffected.
- Sessions idle for 30 minutes with nothing attached are closed.
node-ptyis an optional dependency. Without it the Chat tab works and the Terminal tab reports that it is unavailable.- Only the Windows installer is built today. The source runs on macOS and Linux, but neither is packaged or tested.
MIT © 2026 hasong.
That covers the code in this repository. It does not extend to what it depends
on: the Claude Code CLI and the @anthropic-ai/claude-agent-sdk package it is
built against are Anthropic's, licensed under
Anthropic's own terms,
not MIT. They are installed from npm and from Anthropic's installer rather than
vendored here.