Mastering the OpenCode Terminal User Interface

Jun 30, 2026 min read

Ollama is running. The model loaded. You’ve confirmed it generates clean code from the command line. Now you open a coding session and immediately hit the workflow problem: you type a prompt in one terminal, copy the output, switch to your editor, paste it, check the line numbers, realize they’re wrong, go back to the terminal, correct the prompt, copy again, paste again.

The copy-paste loop is exactly what OpenCode eliminates.

Installing and Connecting OpenCode

Getting the CLI

OpenCode requires Node.js. Install via npm:

npm install -g opencode-ai

Verify the installation:

opencode --version

Launch OpenCode from your project directory:

cd /path/to/project
opencode

The TUI opens in your terminal: conversation history at the top, active context panel on one side, chat input at the bottom. If you haven’t configured a provider, it prompts you on first launch.

Wiring OpenCode to Ollama

Create or edit ~/.config/opencode/opencode.json:

{
  "provider": {
    "ollama": {
      "name": "Ollama",
      "options": {
        "baseURL": "http://localhost:11434/v1"
      },
      "models": {
        "my-coder": {
          "name": "my-coder",
          "tools": true
        }
      }
    }
  }
}

Two details matter here. The baseURL uses the /v1 suffix — Ollama exposes an OpenAI-compatible endpoint at that path, and OpenCode expects the OpenAI API format. The "tools": true flag enables function calling, which is how OpenCode applies file diffs as actual filesystem operations rather than just printing text.

After saving, restart OpenCode and select the model with /model my-coder at the chat input.

Essential OpenCode Commands

Managing Code Context: @ and /new

The quality of AI-generated code correlates directly with the quality of context you provide. Too little context and the model invents function signatures. Too much context and the KV cache overflows VRAM, slowing generation to a crawl.

To attach a file to the model’s active context window, type @ followed by the filename for fuzzy searching:

@parser.py

This reads parser.py and adds its full contents to the KV cache. The model can now reference the functions, imports, and type definitions in that file when generating changes.

To free KV cache memory and focus the model on what you’re currently working on, clear the session context by starting a new one:

/new

On an 8GB VRAM setup (like an RTX 4060 running Llama-3 8B), active context management is the difference between generating at 45 tokens/sec and degrading to 3 tokens/sec. Clear your context the moment you switch tasks.

The core workflow pattern — Attach-Prompt-Apply-Clear — keeps your sessions fast and your context focused:

  1. Use @ to attach the file you’re editing (and any interfaces it references)
  2. Prompt the model for the specific change
  3. Review and apply the generated diff
  4. Use /new to clear the context when moving to an unrelated task

Diagram

This diagram visualizes the OpenCode TUI architecture and core workflow, illustrating how the terminal interface manages context, communicates with the local Ollama API, and applies code diffs directly to the filesystem.

C(o@ntfeixlte,MannaegwO(L(e)lLLGrloMeacnmaEealnrhgaAoitPsneItes)DC(i(hRvfOUae1fpstq))eeunr/eCsoTPtdereroDmmiTipfUntfIa)l)C(L(D(o!oPiWmcrfrmsaofiahljtneeAedlFcpslitpElltxceCioemsoecdydrdusseit)t)soekrm)

Visual Notes:

  • The Context Manager and Prompt feed directly into the Ollama API, utilizing the KV cache.
  • The LLM Engine generates a diff, which the Diff Applier writes directly to the Local Filesystem.
  • The Command Executor interacts directly with the filesystem, independent of the LLM generation loop.

Applying Diffs and Running Commands

When the model generates a code change, OpenCode presents it as a unified diff in the TUI — additions in green, removals in red. Press Enter to apply or Esc to reject. The change writes directly to your file on disk. No clipboard involved.

You can also run shell commands from inside OpenCode by prefixing them with !:

!pytest tests/test_parser.py -v

OpenCode executes the command and pipes the output back into the conversation. The model reads the test results and can suggest fixes based on the actual error messages — without you copying error text from one window to another.

Hands-On Example: Refactoring a Function

The task: Refactor a CSV parser and verify the tests still pass, entirely within the terminal.

Starting file, parser.py:

def parse_csv(filepath):
    import csv
    data = []
    f = open(filepath)
    reader = csv.DictReader(f)
    for row in reader:
        data.append(row)
    f.close()
    return data

Launch OpenCode in the project directory:

cd ~/projects/data-pipeline
opencode

Add the file to context:

@parser.py

Send the prompt:

Refactor parse_csv to use a context manager for file handling, add a type hint for the return value, and raise a descriptive ValueError if the file doesn't exist.

OpenCode sends the file content plus your prompt to Ollama. The model generates the refactored function and presents a diff (note: list[dict] requires Python 3.9+):

import csv
from pathlib import Path

def parse_csv(filepath: str) -> list[dict]:
    path = Path(filepath)
    if not path.exists():
        raise ValueError(f"CSV file not found: {filepath}")
    with open(path, newline='') as f:
        return list(csv.DictReader(f))

The diff shows: import moved to top level, open() replaced with a context manager, type hints added, error check inserted. Review it — accept or reject.

Run the tests immediately after accepting:

!pytest tests/test_parser.py -v

The test output appears in the conversation. If a test fails, the model reads the failure message and can generate a fix. When tests pass, start a new session to clear the context and move on.

/new

The entire sequence — prompt, review, apply, test — takes about 2 minutes without leaving the terminal.

Best Practices

Use /new aggressively. KV cache memory on an 8GB VRAM setup is finite. Every file you attach stays in the cache and slows subsequent generation. After finishing a task, clear the session immediately.

Review every diff before accepting. Local 8B models handle targeted, single-file changes well, but occasionally hallucinate line numbers or inject variables that don’t exist in your actual file. The diff view is there to catch this — read it. One line of misaligned context can introduce a silent bug.

Avoid @folder dumps. Adding the entire project directory pushes hundreds of kilobytes into the context window and immediately exhausts VRAM on anything less than a 16GB GPU. Attach individual files. If you need cross-file context, attach the two or three most relevant ones.

Start /new sessions for unrelated tasks. OpenCode carries conversation history in the context window. A session that started with a database refactor will color suggestions for an unrelated frontend component. Clear it when switching domains.

Troubleshooting

Problem: OpenCode hangs when trying to apply a diff.

Cause: The model hallucinated line numbers or file structure that don’t match your actual file. The patching process fails because the context markers don’t align.

Fix: Reject the diff. Ask the model to rewrite the entire function block rather than generating a partial patch. Full replacements are more reliable than line-specific diffs from 8B models.

Problem: Connection refused when OpenCode connects to Ollama.

Cause: Ollama isn’t running, or the baseURL in opencode.json is missing the /v1 suffix.

Fix: Confirm Ollama is running (curl http://localhost:11434/api/tags should return JSON). Check the config — the URL must be http://localhost:11434/v1, not http://localhost:11434.

Problem: “Tools not enabled” error.

Cause: The model entry in opencode.json is missing "tools": true.

Fix: Add "tools": true to the model’s config entry, save, and restart OpenCode. Without it, the model generates code but OpenCode can’t apply the output as filesystem diffs — it can only print it.

Key Takeaways

OpenCode’s value is eliminating the gap between AI generation and file editing. The workflow centers on three commands: @ to provide context, a natural-language prompt to request the change, and diff acceptance to write it to disk. The /new command is what keeps the workflow fast — managing KV cache actively is the difference between a productive session and a frustrating one.

Local 8B models handle targeted, file-specific changes well. They struggle with large-scale cross-file refactoring. Use OpenCode for what it does best: focused, single-file changes that you’ve reviewed before accepting.

Sources