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, entry packages/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 as project/instance.ts, config/config.ts, tool/tool.ts, and session/prompt.ts.
  • Docker images and CI pipelines are defined in packages/opencode/Dockerfile and .github/workflows/*.yml.
  • SDKs for external consumption sit under sdks/ and the Nix flakes under nix/.

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:

  1. Agent selection – session/index.ts chooses the build or plan sub‑agent.
  2. Prompt handling – session/prompt.ts builds the request sent to the LLM back‑end (Rust binary built via Cargo).
  3. Tool execution – tool/registry.ts resolves 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.ts each 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.ts has 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_TOKEN permissions (.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 USER to Docker image.
  • Low – Set timeout-minutes on 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.