# 0003 · Go, shipped as a single static binary

**Status:** Accepted · 2026-09-22 · supersedes an initial TypeScript decision

## Context

The first draft specified a TypeScript monorepo — defensible, since the MCP SDK, Typesense client,
and web framework are all first-class there. On review, the deployment story decided it.

CoDNA is self-hosted software. Most installations will be someone in an infrastructure team trying
it on a spare VM. What they have to install is a feature.

## Decision

Go 1.27+, compiled to one static binary carrying the API, MCP server, outbox worker, scheduler, and
web UI. The Svelte UI is built with Vite and embedded via `embed.FS`, so Node is a build-time
dependency and never a runtime one.

Supporting choices: **sqlc** over an ORM, **goose** for migrations, **pgx v5** for the driver.

## Consequences

- `docker run codna/codna serve`. No runtime, no `node_modules`, no version manager.
- sqlc means writing SQL by hand. The load-bearing queries here are recursive CTEs for link traversal
  and `FOR UPDATE SKIP LOCKED` for the scheduler — an ORM would obstruct both.
- Goroutines plus `LISTEN`/`NOTIFY` give the outbox worker and scheduler a natural home in-process.
  No queue, no sidecar.
- Low, predictable memory, which matters on the spare VM.
- **The repository is polyglot.** The UI is TypeScript and always will be.
- **Document extraction is weaker than Python's.** PDF especially; stated plainly in
  [ingestion.md](https://codna.me/docs/ingestion.md) with the mitigations.
- More boilerplate around JSON and validation than Zod would need.

## Alternatives rejected

**TypeScript.** One language across the stack, the best MCP and Typesense tooling, and Zod schemas
that feed MCP tool definitions directly. Rejected on deployment: a Node runtime plus a dependency
tree is exactly the install friction that makes people bounce off self-hosted software.

**Rust.** Stronger guarantees and the same single-binary benefit, at a development pace this project
cannot afford, for a system whose hard parts are SQL and permissions rather than performance.
