Architecture Overview
How CloudCLI UI is structured internally — the stack, directory layout, and how the key pieces connect.
Want to contribute? Start with the CONTRIBUTING.md in the repository for commit conventions, branch naming, and the pull request process. Then come back here to understand how the codebase is structured.
This page is aimed at contributors and developers who want to understand how CloudCLI UI works internally before reading or modifying the code.
Stack
| Layer | Technology |
|---|---|
| Frontend | React + Vite |
| Backend | Node.js + Express |
| Real-time communication | WebSockets (ws) |
| Terminal emulation | node-pty |
| Code editor | CodeMirror |
| Process management (optional) | PM2 |
| Containerisation (Cloud) | Docker (one container per user) |
Directory Structure
claudecodeui/
├── src/ # React frontend
│ ├── components/ # UI components (chat, file explorer, git, etc.)
│ ├── hooks/ # Custom React hooks
│ └── lib/ # Shared utilities
├── server/ # Express backend
│ ├── routes/ # REST API endpoints
│ ├── websocket/ # WebSocket handlers
│ └── lib/ # Server utilities (session discovery, MCP sync, etc.)
├── public/ # Static assets
├── .env.example # Environment variable reference
└── package.jsonHow It Fits Together
The Express server does three things:
- Serves the React app as static files in production
- Exposes a REST API for file operations, Git operations, session management, and MCP config
- Handles WebSocket connections for real-time streaming of agent output to the browser
The browser connects over HTTP to load the app and make API calls, and over a persistent WebSocket connection to stream agent output in real time.
Sessions
When the server starts, it scans ~/.claude/projects/ (and equivalent paths for Cursor, Codex, and Gemini) to discover existing sessions. Each session maps to a directory on the filesystem.
When a user starts or resumes a session in the UI, the server uses node-pty to spawn the agent process in a pseudo-terminal, then streams its stdout/stderr to the browser over a WebSocket connection. Input from the browser — chat messages, keystrokes in shell mode — goes back over the same socket.
Sessions created in the UI are immediately available in the terminal via claude -r because they share the same ~/.claude directory.
MCP Config Sync
MCP server configuration is stored in ~/.claude.json. The CloudCLI UI backend reads and writes this file directly — there is no separate config layer. Any change made via the UI settings panel is written to the same file the Claude Code CLI reads, so the two stay in sync automatically.
File and Git Operations
The file explorer and Git explorer use standard Node.js fs operations and simple-git respectively. All file operations are scoped to the project directory the user has open — the server does not allow traversal outside the configured WORKSPACES_ROOT.
CloudCLI Cloud Differences
In the self-hosted version, everything runs on one machine and sessions use the local filesystem. In CloudCLI Cloud, each user gets an isolated Docker container. The CloudCLI UI server runs inside that container alongside the agent, so the architecture is identical from the frontend's perspective — the only difference is the environment it runs in.