Documentation
Claude Code UI is a desktop console for Claude Code. It drives the real claude CLI (stream-json protocol, the same options as the SDK and the VS Code extension) and shows sessions more readably than a terminal. The interface is available in French and English; dark themes only.
Installation#
Download the installer for your system from the GitHub releases page. No .NET SDK or particular browser is needed: the app bundles its own server and uses the system web view.
| System | File | Note |
|---|---|---|
| Windows 10/11 | -setup.exe or .msi | WebView2 is already included in Windows 11. |
| macOS | .dmg aarch64 (Apple Silicon) | Signed and notarized by Apple. Intel Macs are not supported (macOS 26 is their last version). |
| Linux x64 | .AppImage or .deb | Requires WebKitGTK 4.1 (libwebkit2gtk-4.1-0 on Debian/Ubuntu, already installed on most desktops). |
The Windows installer is not signed. SmartScreen therefore shows a warning on first launch. This is expected; the steps are below.
Windows
SmartScreen shows "Windows protected your PC". Click "More info", then "Run anyway".
macOS
The app is signed with a Developer ID and notarized by Apple: it opens normally, no workaround needed.
Verify your download
Each release ships a SHA256SUMS file and GitHub build-provenance attestations. To verify a file: gh attestation verify <file> -R Atypical-Consulting/ClaudeCodeUI.
Updates
Every version after 0.1.0 updates itself: a few seconds after startup it checks the latest GitHub release and offers to install the new one and restart. To check at any time: Check for Updates… (app menu on macOS, Help menu on Windows and Linux), or in Settings › Appearance and the command palette. Updates are signed, and the signature is verified before anything is installed. Version 0.1.0 has no updater: install the next version by hand once.
Linux
For the AppImage, make the file executable, then run it:
chmod +x Claude*.AppImage ./Claude*.AppImage
Requirement: Claude Code
The app launches the claude CLI installed on your machine: it must be installed and signed in.
# macOS, Linux, WSL curl -fsSL https://claude.ai/install.sh | bash # Windows (PowerShell) irm https://claude.ai/install.ps1 | iex
Then run claude once in a terminal to sign in. If claude is not found in the PATH, the app shows the "Claude Code not found" screen instead of the start screen. On macOS, it reads the PATH of your login shell, so an installation done through ~/.zshrc is picked up.
First launch#
The start screen asks "What are we working on?". It gathers everything a session fixes before it begins:
- Working folder: the folder where
claudewill run. Recent folders are offered in one click. - Isolation: "New worktree" creates a git worktree
worktree-<name>from the current branch, with a generated name ("brave-gliding-otter") that "Edit" replaces. The option only appears if the folder is a git repository. - Permissions: the session mode. "Settings" by default: the CLI applies your
permissions.defaultMode, as in the terminal. - Ctrl ⏎ or "Start" opens the session, as
claudedoes in a terminal: the first message is written in its composer, where the slash commands are already loading.
| Mode | Behavior |
|---|---|
default | Asks before every sensitive tool. |
acceptEdits | Accepts edits, asks for the shell. |
plan | Read-only, proposes a plan. |
auto | Never interrupts; use with care. |
The bypassPermissions and dontAsk modes are deliberately not offered.
Sessions and permissions#
A session shows Claude's text live, a thinking indicator, and the tool log: one line per call (Read, Grep, Edit, Bash, Write…), colored by tool. Selecting a line opens it in the inspector, with Output, Input and JSON tabs. Ctrl I shows or hides the inspector.
Responding to a permission
When Claude wants to edit a file or run a command, the request appears in the inspector: the full diff for an edit, the exact command for the shell.
| Action | Key | Effect |
|---|---|---|
| Allow | ⏎ | This call only. |
| Whole session | Shift ⏎ | Applies the rule proposed by the CLI to this session only: no settings file keeps it. The button only appears when it proposes one. |
| Deny | Del | Claude receives the refusal. |
These keys act when focus is not in a field or on a button. Esc interrupts the running session.
Several sessions
Sessions run in parallel and stay listed in the rail. The overview (Ctrl ⇧ O) shows their state, mode, last action and cost, and the decision queue gathers pending permissions (J K to navigate, ⏎ to open). Ctrl ⇧ A jumps straight to the first pending decision.
The Ctrl K palette finds an active or recent session and runs an action. A recent session reopens with its history. If the claude process stops, a card says so and lets you restart the session. The rail also shows the 5 h / 7 day quota, and each turn its cost and duration.
Composer#
The input field carries the settings for the next turn. Ctrl ⏎ sends; during a turn, the button becomes "Interrupt" (Esc).
- Model: the list comes from the CLI; the choice applies to the current session.
- Effort: the levels offered by the model, when it has any.
- Fast: the CLI's fast mode, greyed out with its reason when unavailable.
- Ultracode: turns on the CLI's ultracode setting for the next turn, which becomes a multi-agent workflow. Greyed out when the account or model does not allow it.
/commands: typing/opens the session's commands and skills, filtered as you type. ↑ ↓ to choose, Tab to insert, Esc to close.
Below the field: the turn duration, the session cost, the number of tools and the context used.
Subagents#
When Claude delegates to a subagent (the Agent or Task tool), the call gets its own line in the log. Opening it shows what the agent writes and the tools it calls. During an Ultracode turn, the workflow is displayed with its phases and agents, and the send button becomes "Stop workflow".
Worktrees#
The Worktrees page finds the worktrees of the repositories from your recent sessions, ranks them, and says why for each. The first criterion that applies wins:
- Active
- A session from the app is running there, or an external
claudesession whose process is alive. Never touched. - Orphaned
- The folder was deleted by hand and git still references it. Cleaned up with
git worktree prune. - Needs review
- Uncommitted modified files, commits never pushed, a stale lock or one without a pid, a detached HEAD outside the base, or a branch not yet in the base. Waits for your decision.
- Safe
- Already merged into the base (including by squash) and nothing local. Can go.
"Delete" or "Prune" adds a worktree to the plan; the inspector shows the git commands before running them, and "Add the safe worktrees" takes them all at once. A Needs review worktree with unpushed commits offers "Push".
Safeguards. Never --force, -f or -D: branches are removed with git branch -d, which git itself refuses if they are not merged. Right before each deletion, the worktree's state is read again; if it changed, it is skipped. The page also flags a .claude/worktrees/ that git does not ignore, which a git add . would add to the repository.
MCP extensions#
The Extensions page shows what the session has loaded: MCP servers, skills, agents and plugins. MCP servers are filtered by state (connected, authentication, failed); a toggle enables or disables a server for the current folder, and a failed server restarts with "Retry". Connecting a server that requires authentication is not yet available in the app.
Themes#
Five themes, all dark: Graphite, Encre, Ristretto, Mousse and High contrast. The Appearance page also sets the code size. Both choices are remembered. This site uses the same themes: the picker is in the rail.
Keyboard shortcuts#
On macOS, ⌘ works everywhere Ctrl is shown.
| Key | Action | Where |
|---|---|---|
| Ctrl K | Open or close the palette (sessions and actions) | anywhere |
| Ctrl N ou Alt N | New session (Alt N when the browser keeps Ctrl N) | anywhere |
| Ctrl I | Show or hide the inspector | anywhere |
| Ctrl ⇧ O | Overview | anywhere |
| Ctrl ⇧ A | Go to the first pending decision | anywhere |
| Esc | Close the open palette or menu; otherwise interrupt the running session | anywhere |
| ⏎ | Allow | permission shown |
| Shift ⏎ | Allow for the whole session | permission shown |
| Del | Deny | permission shown |
| Ctrl ⏎ | Send the message, or start the session | composer, start screen |
| ↑ ↓ Tab | Choose and insert a / command | composer |
| ↑ ↓ ⏎ | Browse and open a result | palette |
| J K ⏎ | Browse and open a decision (also ↓ ↑) | overview |
| ⏎ or Space | Open a log line, choose a model | log, model menu |
Permission keys only apply when focus is not in a field, on a button or on a link.
Security#
- Loopback only. The desktop app starts its server over HTTP on
127.0.0.1, on a free port. Host filtering answers 400 to any request whose Host header is not127.0.0.1, which blocks DNS rebinding. - Token per launch. The server draws a random token at every start and only hands it to the window, through its standard output. The first request presents it; it is then kept in an
HttpOnly,SameSite=Strictcookie and compared in constant time. - Markdown without HTML. Replies go through Markdig with raw HTML disabled: a reply cannot inject markup into the page.
- Lifetime tied to the window. The server stops when the window closes.
In development mode (dotnet run), the web server listens on http://localhost:5284, without a token.
Development#
Requirements: .NET 10 SDK. For the desktop app: Rust (stable), Node 20+ and the Tauri prerequisites for your system.
dotnet run # web server alone on http://localhost:5284 dotnet run -- --self-check # built-in checks, non-zero exit code on failure
Desktop app, in the desktop/ folder:
cd desktop npm install npm run server # publishes the self-contained server for your machine into src-tauri/server npm run dev # launches the Tauri window npm run build # builds the installers into src-tauri/target/release/bundle
The Tauri shell launches ClaudeCodeUI --desktop-port 0 --parent-pid <pid>, shows a loading screen, then opens the interface. Re-run npm run server after every change to the .NET code.
Publishing#
- Commits follow Conventional Commits:
feat:,fix:,docs:,ci:,chore:. - On every push to
main, release-please opens or updates a release PR: CHANGELOG, and the version inClaudeCodeUI.csproj,tauri.conf.jsonandCargo.toml. - Merging that PR creates the tag and the GitHub release. The
release.ymlworkflow then builds the Windows, macOS (Apple Silicon) and Linux installers and attaches them to the release.
This site is published to GitHub Pages by the pages.yml workflow whenever the site/ folder changes on main.
Known limitations#
Open problems are tracked on GitHub:
Another problem? Open an issue.