The Problem
Developers who use Claude Code need a local, self‑contained IDE that can run Claude agents without configuring a remote service. The current workflow requires manual setup of the Claude Agent SDK, handling of prompt caching, and separate tooling for file‑system actions, which slows down rapid prototyping and limits offline use.
What This Does
claudius is a desktop application built on the OpenCode foundation and the Claude Agent SDK. The UI lives in packages/app (React/Vite) and the native host is a Tauri desktop shell in packages/desktop. Core agent orchestration resides in the packages/opencode workspace, which provides:
packages/opencode/src/project/instance.ts– the central project model that 38 other modules import.packages/opencode/src/util/log.ts– lightweight logger used across the stack.packages/opencode/src/server/server.ts– HTTP server that exposes the agent APIs to the UI.
The repo is a portfolio of four loosely coupled projects (app, desktop, opencode, sdks) that share a common TypeScript‑first codebase and a small Rust component for Tauri (packages/desktop/src-tauri/src/lib.rs).
How It Is Wired
Execution begins with the Electron‑like Tauri bootstrap defined in packages/desktop/src-tauri/Cargo.toml. The generated binary loads the bundled Vite dev server (packages/desktop/vite.config.ts) which serves packages/app/index.html. React mounts at packages/app/src/app.tsx, which immediately imports packages/app/src/components/session/index.ts and packages/app/src/utils/index.ts.
The UI creates a ProjectInstance by calling new ProjectInstance() from packages/opencode/src/project/instance.ts. This module pulls in configuration (config/config.ts), file‑system helpers (util/filesystem.ts), and the LSP server (lsp/server.ts). The server (packages/opencode/src/server/server.ts) starts an HTTP listener that the UI reaches via fetch calls defined in packages/app/src/api.ts (not listed but implied by the import graph).
Because ProjectInstance is the most‑connected hub (38 inbound edges, only 3 outbound), any change there ripples through the majority of the codebase. It also participates in a circular import with config/config.ts and project/project.ts, which forces the runtime to evaluate modules in a non‑deterministic order and hampers refactoring.
All file‑system mutations (read/write, glob, grep) flow through packages/opencode/src/util/filesystem.ts, which is invoked by the agent server and the UI. The Rust side (src-tauri/src/lib.rs) only exposes a thin bridge for native dialogs and does not contain business logic.
How To Use It
# Clone the repository
git clone https://github.com/moses-y/claudius
cd claudius
# Install Node‑side dependencies (Bun is the lockfile format)
bun install
# Run the web UI in development mode
bun run dev # starts Vite, opens http://localhost:5173
# Build and run the desktop app (requires Rust toolchain)
cargo tauri dev # launches the Tauri window with the bundled UI
Configuration files are under packages/opencode/:
opencode.jsonc– project‑level settings read byProjectInstance.packages/opencode/Dockerfile– optional container build for the server component.
No environment variables are required for a basic local run; the SDK picks up the Claude API key from the standard CLAUDE_API_KEY env var if agents need external access.
Real‑World Use
A software team can ship a private “Claude‑powered IDE” to developers’ laptops. A typical workflow:
# Open the desktop app
claudius # (binary from `cargo tauri dev`)
# In the UI, open a folder → the app creates a ProjectInstance
# Write a prompt → the agent SDK caches the response locally
# Switch to Planning mode → UI disables write‑actions, only read‑only LSP queries are sent
All interactions stay on the local machine; no external server is required unless the Claude API key is provided.
Code Health & Issues
- High – Import cycles (19) – e.g.,
packages/opencode/src/project/instance.ts,config/config.ts,project/project.ts. Break cycles by extracting shared types or using lazy imports. - High – Hub module –
project/instance.tsis depended on by 38 modules; keep it stable and small. - High – Oversized files –
config/config.ts(1072 lines) and others; split by responsibility. - High – Deep nesting – up to 9 levels in
server/server.tsandbasic-tool.tsx; refactor to early returns. - Medium – Empty catch blocks – silent errors in
config/config.ts,global/index.ts. Add logging or rethrow. - Medium – Duplicated code blocks – repeated 6‑line snippets across 91 files; extract helpers.
Repository‑wide health audit
- Pin GitHub Actions to commit SHAs (
.github/workflows/*). - Remove
continue-on-errorfrom correctness steps (publish.yml). - Declare least‑privilege
GITHUB_TOKENpermissions (test.yml). - Add Dependabot (
.github/dependabot.yml). - Pin Docker base image by digest (
packages/opencode/Dockerfile). - Add a non‑root
USERto Docker images. - Set
timeout-minuteson workflow jobs (publish-github-action.yml).
All other hygiene items (tests, CI, license, lockfiles, no committed secrets) are present.
The Bottom Line
claudius delivers a functional, locally runnable Claude IDE with a clear separation between UI, native host, and agent server. The codebase works but suffers from a few structural hot spots—import cycles, oversized hub modules, and deep nesting—that will increase maintenance cost. It is suitable for teams comfortable with TypeScript, Rust/Tauri, and Docker who need an offline Claude development environment, provided they allocate effort to resolve the identified hot spots and tighten CI security.