Course · OpenCode · Getting started
Install OpenCode and meet the TUI
Before you trust a terminal coding agent with a repository, install OpenCode, start it inside the repository you’ll be working against, and look at what it actually is - because most of the unease about terminal agents is really unease about a black box, and OpenCode’s box opens cleanly into two parts you can see.
The repository this course works against is feedmill, the illustrative project named across the track: a small Go CLI plus an HTTP sync server that pulls dozens of RSS, Atom, and JSON feeds, dedupes them, and serves a reading queue you read from the terminal and can run unattended on a cron. It mostly works. It’s lightly documented. It’s exactly the kind of typed, parser-heavy, many-moving-parts codebase where you’d want a competent pair - and exactly the kind you don’t want a black box let loose in. Good test subject. Nothing on this page depends on feedmill’s contents, so your own repo works just as well.
Install it
Section titled “Install it”OpenCode is an open-source, terminal-first coding agent built by the team behind SST and Terminal - now operating as Anomaly (github.com/anomalyco/opencode). The one-liner that works everywhere is the install script:
$ curl -fsSL https://opencode.ai/install | bashIf you’d rather go through a package manager you already trust, all of these land the same binary:
$ npm install -g opencode-ai # npm (package is opencode-ai, not opencode)$ brew install anomalyco/tap/opencode # Homebrew (project-maintained tap, updated often)$ paru -S opencode-bin # Arch / AURThese are the documented methods as of October 2026; the OpenCode docs carry the current list if any of them moves.
Confirm it’s on your path before you point it at anything that matters (-v is the short form):
$ opencode --versionThat’s the whole install. No account wall to clear before you can look around, though an answer does need a model provider (the first step below) - authentication gets a page of its own, because OpenCode is provider-agnostic and choosing a model is a real decision you shouldn’t rush. For now you just want to see the surfaces.
Start it in the repo and meet the TUI
Section titled “Start it in the repo and meet the TUI”Drop into feedmill and run the bare command:
$ cd feedmill$ opencodeWhat comes up is not a line-by-line REPL waiting for one command at a time. It’s a full-screen TUI - a terminal user interface that takes over the window, with your conversation filling the pane and an input box pinned at the bottom. OpenCode is built by terminal people, and the TUI is the front door, not an afterthought. You navigate it with the keyboard, scroll the transcript, switch models inline, and run slash commands. One of those, /init, runs a guided setup that creates or updates the project’s AGENTS.md context file.
One dependency first: a model answering takes a provider. If you haven’t chosen one yet, run /connect in the TUI and connect any provider you have a key for - a quick choice is fine for this look-around, and bring your own model (the next page) makes the real choice.
Then type a read-only question as your first move - nothing that asks for a file change. Know what protects you here in build: only the wording of the question. Under default permissions the build agent that OpenCode starts in can edit files and run shell commands without asking (most permissions default to allow as of October 2026; see the permissions documentation). If you want a guard on edits, press Tab to switch to the plan agent first: it denies the edit tools, though it does not gate shell commands (as of October 2026, v1.18.32, per agent.ts; the agents documentation describes both as ask; the shipped code is what runs, so treat plan as edit-denied and shell-unguarded). In build, a question keeps this look-around safe by intent, not by enforcement; Ship your first reviewed change sets the config that makes edits wait for your approval.
If you’d rather read on first, here is a stylized version of what comes back, so you can see what to expect:
> what is this project, and how does the CLI talk to the sync server?
read README.md read main.go, cmd/sync/main.go (2 files)
feedmill is a small feed aggregator in Go with two entry points: a root CLI (main.go) that opens the SQLite store and runs one sync with -once, and a sync server (cmd/sync) that serves /healthz and /sync over HTTP. The CLI opens the store directly rather than going through the server.No file was touched, and you learned two things. You’ve learned the lay of feedmill - a clean answer to a question you’d otherwise have to spelunk for. And you’ve learned how this agent behaves: it reads the relevant files first and tells you which ones, then answers. That’s the loop, covered properly in Understand one turn of the loop; for the moment just note that the first thing it did was read, not write.
To leave the TUI, the agent’s own /exit command (or ctrl+x q, the default keybind as of October 2026; see the keybinds documentation) drops you back to your shell.
The second surface: it’s a client of a server
Section titled “The second surface: it’s a client of a server”Here’s the part that turns the black box transparent. When you ran opencode just now, you didn’t only start a chat window - you started a server, and the TUI is a client talking to it. OpenCode has a genuine client/server architecture under the hood, and you can run the server by itself with no UI attached at all:
$ opencode serveopencode server listening on http://127.0.0.1:4096The startup line is stylized (your build may word it differently), but the address is the documented default: the server binds 127.0.0.1:4096 as of October 2026 (server documentation). That default is reachable only from your own machine, and the server has no authentication unless you set OPENCODE_SERVER_PASSWORD, which turns on HTTP basic auth. opencode serve is a headless HTTP server exposing an OpenAPI-described API - sessions, messages, files, agents, the lot. It’s the same engine the TUI drives; the TUI is just the most convenient of several possible clients. serve holds the terminal, so browse the API surface from a second terminal, at the running server’s docs endpoint:
$ curl http://127.0.0.1:4096/docWhy should a skeptic care? Because it’s the proof that OpenCode isn’t a magic terminal wrapper - it’s a controllable program with a documented interface. The same server is what makes automation possible: you can drive OpenCode against your repo with no human at the keyboard at all. And it’s what underlies the non-interactive form you’ll use for scripting:
$ opencode run "list the feed-source parsers and which formats each handles"Same engine, no TUI - one prompt in, an answer out, suitable for a pipe or a cron line. The sharing-and-headless chapter leans on opencode run hard; for now it’s enough to know the headless path exists and is the same brain as the pretty one.
So the box is open. There’s an interactive surface - the full-screen TUI you just talked to - and a programmatic one - the server it’s quietly a client of, also reachable as opencode serve and opencode run. Nothing is hidden, and nothing has touched a file yet. The one thing standing between you and real work is the decision you deliberately skipped: which model does the thinking. OpenCode runs almost any provider you can name, and that choice is yours to make rather than a default to accept - so bring your own model.