A beautiful desktop GUI for Claude Code. Built with Electron; runs on macOS, Linux, and Windows.
Agent-first. Black, white, and green — with a light mode. Minimal. Fast.
- macOS (Apple Silicon) — latest DMG (signed + notarized — just drag to Applications)
- Linux — build locally with
npm run build:pacmanornpm run build:appimage(see below) - Intel Mac / Windows — run from source (see below)
- Chat interface with conversation history and persistence
- Light / Dark / System theme — auto-switches with the OS
- Workspace panel — file tree, inline diffs, live Edits/Tools tabs so you can watch exactly what the agent touched
- GitHub PR panel (via
ghCLI) — browse PRs in the current repo, read review threads + comments, reply inline, or hand a thread to chat with Help me respond - Attachments — attach files or images (inline previews) right in the prompt
- Per-chat git worktrees — isolate agent work from your main checkout
- Integrated terminal (xterm.js) inside the app
- Memory MCP — save takeaways across conversations
- Permission approvals surfaced as UI dialogs (via
--permission-prompt-tool) - Session persistence — conversations maintain context across messages
- Markdown rendering with syntax-highlighted code blocks
- Custom frameless titlebar and resizable panels
- Claude Code CLI installed and authenticated
- Node.js v18+
- GitHub CLI (optional — only needed for the PR panel; run
gh auth loginfirst) - A C/C++ toolchain for
node-pty's native rebuild:- macOS: Xcode Command Line Tools (
xcode-select --install) - Linux:
build-essential(Debian/Ubuntu) orbase-devel(Arch) - Windows: windows-build-tools or the "Desktop development with C++" Visual Studio workload
- macOS: Xcode Command Line Tools (
git clone https://github.com/oluwatimio/code-gui.git
cd code-gui
npm install
npm startgit clone https://github.com/oluwatimio/code-gui.git
cd code-gui
pnpm install
pnpm startPackaged installers currently target Linux. macOS and Windows users run from source with npm start / pnpm start.
npm run build:pacman
sudo pacman -U dist/code-gui-1.1.0.pacmanThe app will appear in your application launcher as Claude Code.
npm run build:appimage
chmod +x dist/Claude\ Code-1.0.0.AppImage
./dist/Claude\ Code-1.0.0.AppImagenpm run buildIf you want a packaged .app / .dmg on macOS, add a mac target to the build block in package.json:
"mac": {
"target": ["dmg", "zip"],
"icon": "assets/icons/",
"category": "public.app-category.developer-tools"
}Add a build script alongside the existing ones:
"build:mac": "electron-builder --mac"Then:
npm run build:mac
open "dist/Claude Code-1.0.0.dmg"Builds produced this way aren't signed or notarized, so macOS Gatekeeper will complain on first launch. For personal use, right-click the app → Open to bypass, or strip the quarantine attribute:
xattr -cr "/Applications/Claude Code.app"Distributing to other users requires an Apple Developer signing identity and notarization — out of scope here.
code-gui/
├── main.js # Electron main process
│ # - Spawns claude -p with --session-id/--resume
│ # - HTTP bridge for permission approvals
│ # - gh CLI integration for the PR panel
│ # - MCP config generation (temp file)
├── preload.js # Context bridge (IPC + markdown rendering)
├── mcp-permission-server.js # MCP stdio server for --permission-prompt-tool
├── mcp-context-server.js # Memory tool MCP
├── mcp-ask-server.js # Ask-user tool MCP
├── lib/claude-cli.js # Pure logic (argv + stream-event parsing)
├── renderer/
│ ├── index.html # App shell
│ ├── styles.css # Tokens + light/dark palettes
│ └── app.js # UI, state, conversations, panels
├── assets/ # App icons
└── package.json # Build config (electron-builder)
- User sends a message in the GUI
main.jsspawnsclaude -p --session-id <uuid>(first message) orclaude -p --resume <uuid>(follow-ups)- The CLI's
--mcp-configincludes a permission MCP server - When Claude needs permission (file write, bash command, etc.), the MCP server POSTs to an HTTP bridge in the Electron main process, which shows a dialog in the UI
- User clicks Allow/Deny, response flows back through the bridge to Claude
- Claude's response is parsed from stream-json and rendered as markdown; tool uses update the Edits/Tools tabs live
The --permission-prompt-tool MCP tool receives:
{ "tool_name": "Bash", "input": { "command": "..." }, "tool_use_id": "..." }And must return (as text content):
// Allow:
{ "behavior": "allow", "updatedInput": { "command": "..." } }
// Deny:
{ "behavior": "deny", "message": "User denied permission" }| Shortcut | Action |
|---|---|
Enter |
Send message |
Shift+Enter |
New line |
Ctrl+N |
New chat |
Ctrl+B |
Toggle sidebar |
Ctrl+Shift+B |
Toggle workspace panel |
Ctrl+Shift+P |
Toggle PR panel |
Ctrl+Shift+O |
Open file (Spotlight) |
Ctrl+Shift+F |
Search file contents (Spotlight) |
Ctrl+` |
Toggle terminal |
Escape |
Stop generation |
MIT — see LICENSE.