A local desktop GUI for the Claude Code CLI
Features • Requirements • Getting Started • Building an App • How It Works
Clui wraps the claude CLI you already have installed and gives it a desktop interface: multiple live sessions, a live model and effort picker, per-session permission modes, conversation search, image attachments, and light/dark themes. Everything drives the real CLI underneath.
It never modifies your ~/.claude/settings.json. Every model, effort, and permission choice is per-session and stored in Clui's own app-data directory, so the CLI you use in the terminal is left exactly as it was.
Note
Clui is built and tested for macOS on Apple Silicon (arm64). The packaging config and a few native integrations target macOS; it may run elsewhere with adjustments, but that isn't supported yet.
- Multiple live sessions. Each keeps its own
claudeprocess alive in the background. Switching is instant, and in-flight turns keep streaming across a switch. Collapse the session rail to a compact status strip with⌘Bfor a focused view. - Live model & effort selection. The model list is fetched live from your provider; effort switches mid-session without losing context.
- Per-session permission modes. Seven of them, from Interactive (asks before each tool) to Autonomous (asks nothing), plus Adaptive, Auto Edit, and Plan Mode. Changeable mid-session, and two sessions can sit in different modes.
- Conversation search. Find within a conversation (
⌘F) or search across every session at once (⌘⇧F). - Attachments. Paste, drag-drop, or attach images and files directly into a turn.
- Subagent & workflow visibility. Nested agent transcripts and a live workflow progress tree.
- Built for reading. Markdown with syntax highlighting, a command palette (
⌘K), slash-command and@-file autocomplete, session export, and full light/dark theming.
| Requirement | Notes |
|---|---|
| macOS on Apple Silicon | The build target is mac / arm64. |
| Node.js 22.12+ | Vite 7 and electron-vite 5 both require it. Developed on 24.18.0. |
| npm 9+ | Ships with Node. Developed on npm 11. |
The claude CLI |
Install Claude Code, and make sure claude --version works and that you are logged in. Clui drives the CLI already on your machine; it does not ship or install it. |
git clone https://github.com/JRaunak/clui.git
cd clui
npm install
npm run devnpm run dev launches Clui with hot reload. On first run, make sure the claude CLI is authenticated in your terminal; Clui inherits that auth.
Note
Depending on your npm version and policy, npm may gate post-install scripts, and Electron and esbuild download their binaries in one. The repo commits an allowlist (allowScripts in package.json) covering both, so npm install works as-is. You will see a warning about fsevents, which is a macOS file-watcher optional dependency and safe to leave unapproved.
If the app ever fails to launch with a missing-Electron-binary error, approve and reinstall:
npm approve-scripts electron esbuild
npm installTo produce a runnable .app bundle:
npm run packageThe app lands at release/mac-arm64/Clui.app. Open it from Finder, or:
open release/mac-arm64/Clui.appWarning
The app is unsigned. With no Apple Developer code-signing set up, macOS Gatekeeper refuses to open it on the first try. Since you built it yourself, you can allow it in one of two ways:
- Right-click the app → Open → Open, or
- clear the quarantine flag:
xattr -dr com.apple.quarantine release/mac-arm64/Clui.app
Only do this for apps you built or trust.
| Command | Description |
|---|---|
npm run dev |
Launch the app with hot reload |
npm run build |
Bundle to out/ (does not type-check — run npm run typecheck for that) |
npm run typecheck |
Run tsc -b --noEmit |
npm run package |
Build an unsigned arm64 .app dir into release/ |
npm run dist |
Run electron-builder (no DMG target configured yet; a signed installer is the open A10 milestone) |
Clui is split between two processes:
- The main process owns the CLI subprocesses (one per live session), IPC, and the native window.
- The renderer is UI only: a Zustand store with a single persistent event subscription. Switching sessions only changes which slice is active, which is why background sessions keep streaming.
Clui speaks to the claude CLI over its duplex stream-json protocol, and over the stdio control protocol for interactive tool approval.
src/
main/ Electron main: CLI subprocess management, IPC, sessions
preload/ Context-isolated bridge (emitted as index.cjs)
renderer/ React + Tailwind UI (Zustand store, components)
shared/ Types shared across processes
build/ App icon (icon.icns) used by electron-builder
assets/ Icon source SVGs
- "Not logged in · run /login" in every session. The
claudeCLI isn't authenticated in the environment Clui launched from. Confirmclaudeworks from your terminal, then relaunch Clui. - App won't launch after
npm install. Approve the post-install scripts (see the install warning above), then reinstall. - Gatekeeper blocks the packaged app. See the unsigned-app warning above.
- Type or build errors after pulling changes. Run
npm installagain, thennpm run typecheck.
Tip
Issues and pull requests are welcome. Please run npm run typecheck and npm run build before opening a PR.