The Problem
Developers need a locally‑run AI coding assistant that can read, edit, and run code across many languages and environments without sending proprietary source to a remote service. Maintaining such an agent in a single monolith quickly becomes brittle as the codebase grows.
What This Does
opencode ships a collection of seven self‑contained projects that together provide a desktop‑ready AI coding agent, a VS Code extension, a command‑line interface, and supporting SDKs.
- The console UI lives in
packages/console/app(Vite‑powered React, entrypackages/console/app/src/app.tsx). - The web UI lives in
packages/web(static assets,index.html). - Core runtime code resides in
packages/opencode/src/…– modules such asproject/instance.ts,config/config.ts,tool/tool.ts, andsession/prompt.ts. - Docker images and CI pipelines are defined in
packages/opencode/Dockerfileand.github/workflows/*.yml. - SDKs for external consumption sit under
sdks/and the Nix flakes undernix/.
All projects share a common TypeScript toolchain (tsconfig.json files) and are bundled with Cargo for the Rust‑based inference back‑end.
How It Is Wired
Execution starts at the CLI entry github/index.ts (invoked by the install script). It parses arguments, loads the configuration from packages/opencode/src/config/config.ts, and instantiates a ProjectInstance (packages/opencode/src/project/instance.ts).
ProjectInstance is the hub module: 73 other modules import it, giving it the largest blast radius. From there the flow diverges:
- Agent selection –
session/index.tschooses thebuildorplansub‑agent. - Prompt handling –
session/prompt.tsbuilds the request sent to the LLM back‑end (Rust binary built via Cargo). - Tool execution –
tool/registry.tsresolves built‑in tools (e.g.,github-pr-search.ts), which invoke the server (server/server.ts) when remote APIs are needed.
The server module (server/server.ts) imports many utilities (34 outgoing edges) and sits inside a circular dependency with project/instance.ts and config/config.ts, inflating instability (0.83).
All UI projects import the shared logger (util/log.ts), which is imported by 46 modules, making it another hotspot.
Circular imports involve project/instance.ts, config/config.ts, and tool/tool.ts; breaking these cycles would reduce coupling and simplify testing.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/opencode
cd opencode
# Install the CLI globally (npm is the lockfile source)
npm i -g opencode-ai@latest
# Build the Docker image used by the agent
docker build -t opencode:dev -f packages/opencode/Dockerfile .
# Run the desktop UI (beta) – the binary is produced by the Cargo build
cargo build --release -p opencode-agent
./target/release/opencode-agent
Configuration files live in packages/opencode/src/config/config.ts; the default install script respects $OPENCODE_INSTALL_DIR, $XDG_BIN_DIR, $HOME/bin, and falls back to $HOME/.opencode/bin (see README.md for the path priority).
Real‑World Use
A team can run opencode locally, point it at a monorepo, and let the plan agent answer “What files will this change?” before the build agent actually writes edits. The CLI can be scripted in CI pipelines to auto‑resolve lint failures, using the tool/registry to invoke github-pr-search for cross‑repo context.
Code Health & Issues
Measured static analysis (217 findings)
- High – Import cycles (33) – e.g.,
packages/opencode/src/project/instance.ts,config/config.ts,tool/tool.ts. Break cycles by extracting shared types. - High – Hub modules (9) –
project/instance.ts,util/log.ts,config/config.tseach imported by >40 files; keep them stable. - High – Oversized files (12) –
config/config.ts(≈1 k lines) and others; consider splitting. - High – Deep nesting (3) – max depth 7 in
server/server.ts,session/prompt.ts,cli/cmd/tui/app.tsx. Refactor with early returns. - Medium – Empty catch blocks (2) – silent errors in
config/config.ts,global/index.ts. Add logging or rethrow. - Medium – High branching density (1) –
provider/provider.tshas 421 branches; simplify with strategy tables.
Code‑health audit (9 findings)
- High – Pin GitHub Actions to commit SHAs (
.github/workflows/*). - High – Upgrade vulnerable
turbo@2.5.6(CVE‑2026‑45773). - Medium – Declare least‑privilege
GITHUB_TOKENpermissions (.github/workflows/deploy.yml). - Medium – Enable Dependabot (
.github/dependabot.yml). - Medium – Pin Docker base image by digest (
packages/opencode/Dockerfile). - Medium – Add a dependency‑vulnerability scan step in CI.
- Medium – Move >5 MB binaries to Git LFS (
packages/console/app/src/asset/lander/opencode-comparison-min.mp4). - Medium – Add non‑root
USERto Docker image. - Low – Set
timeout-minuteson workflow jobs.
The repo includes tests (75 test files), CI via GitHub Actions, a LICENSE, and lockfiles; no secrets were found.
The Bottom Line
opencode offers a functional, multi‑project AI coding agent with a clear installation path and Docker support, but its core TypeScript layer suffers from heavy coupling, large hub modules, and several import cycles that raise maintenance risk. Teams comfortable managing these refactors can benefit from the ready‑made UI and SDKs; otherwise, the codebase will need systematic modularization before long‑term production use.