opencode Cheatsheet

Nvim keymaps · TUI keys · CLI · config · models

How the nvim integration works: NickvanDyke/opencode.nvim embeds the opencode TUI in a Neovim split (via snacks.nvim's terminal) and adds keymaps that pre-fill prompts with context placeholders like @cursor, @selection, @buffer, @diagnostics. Plugin spec: ~/.config/nvim/lua/plugins/opencode.lua.

Panel control

<leader>ootoggle the opencode panel open/closed
<C-\> <C-n>when focused in the panel, exit terminal-insert mode so you can move with <C-h/j/k/l>
<C-l> / <C-h>jump between code window and opencode pane (from your existing window-nav keymaps)
Auto-reload: the plugin sets vim.o.autoread = true so files opencode edits on disk refresh in your buffer without manual :e.

Ask with context

N <leader>oaprompt prefilled with @cursor: — agent sees the file + cursor position
V <leader>oaprompt prefilled with @selection: — agent sees only the highlighted lines
<leader>o+append @buffer — full file contents fed in
V <leader>oeone-shot "Explain @selection in detail"
Context placeholders resolve at send time. Available: @cursor, @selection, @buffer, @buffers (all open), @diagnostics, @quickfix, @cwd.

Sessions & agent control

<leader>osopen a picker of predefined prompts (snacks picker)
<leader>onstart a fresh session (clears chat history)
<leader>oiinterrupt the agent if it's still streaming

Scroll the conversation

<S-C-u>scroll messages half page up
<S-C-d>scroll messages half page down
The opencode pane is a real terminal — you can also scroll with your terminal's native scrollback (wezterm: Shift+PgUp).

Plugin spec snippet

-- ~/.config/nvim/lua/plugins/opencode.lua
return {
  {
    "NickvanDyke/opencode.nvim",
    dependencies = { "folke/snacks.nvim" },
    init = function() vim.o.autoread = true end,
    config = function() vim.g.opencode_opts = {} end,
    keys = { --[[ see Panel/Ask cards above ]] },
  },
}

When something goes wrong

Panel won't openrun :Lazy sync; verify opencode binary in $PATH
"API key invalid"key is rejected by DeepSeek, not opencode — rotate in 1P, then load_secrets refresh, restart nvim
Model not found / 404swap model in opencode.jsonc from deepseek-v4-pro to deepseek-chat
File didn't reload:set autoread — or :e to force
About the leader: inside the opencode TUI, <leader> defaults to Ctrl+x. So <leader>n below means press Ctrl+x then n. Override in config under keybinds.leader.

INPUT typing your prompt

Entersubmit the prompt
Shift+Enter / Ctrl+Jnewline inside the prompt (multi-line)
Ctrl+Cclear the input box (does not exit)
Ctrl+Vpaste from system clipboard
Ctrl+-undo edit in the input
Ctrl+.redo edit in the input
/ cycle through your prompt history

SESSION control

<leader>nnew session
<leader>llist / switch sessions
Ctrl+Rrename the current session
Ctrl+Ddelete the current session (also exits if no other sessions)
<leader>xexport the session as JSON
<leader>ccompact — summarise old turns to free context
<leader>gshow the session timeline (tree of forks)
Escinterrupt the running agent
Branching sessions: if you re-run a prompt earlier in history, opencode forks a child session. Navigate with <leader>↓ (first child), (cycle children), (parent).

MODELS & agents

<leader>mpick model (filtered to your authed providers)
Ctrl+Apick provider then model (longer list)
Ctrl+Ffavourite the current model
<leader>apick an agent (build / plan / general / custom)
Tabcycle to the next agent
<leader>tchange theme
Ctrl+Pcommand palette — every TUI action by name

NAV messages & views

PgUp / PgDnpage up / down through the message log
Ctrl+Alt+B / Ctrl+Alt+Fsame, alt binding
<leader>ycopy the focused message
<leader>uundo the last agent action (revert file edits)
<leader>rredo
<leader>btoggle sidebar
<leader>sstatus view (token usage, model, agent)
<leader>eopen the message in $EDITOR

EXIT

<leader>qquit the TUI (session is saved — resume with opencode)
Ctrl+C ×2force exit (first Ctrl+C clears input)
Ctrl+Dexit if input is empty
You won't lose work. Sessions persist in ~/.local/share/opencode. opencode session list from a shell shows everything.

Start & run

opencodelaunch TUI in current dir (project root inferred)
opencode PATHlaunch TUI scoped to PATH
opencode run "MSG"one-shot prompt, prints answer, exits
opencode run -m deepseek/deepseek-reasoner "MSG"override the model just for this run
opencode --print-logsstream debug logs to stderr
opencode --log-level DEBUGverbose internals

Providers & auth

opencode auth listshow configured credentials and which env vars opencode sees
opencode auth logininteractive login (stores in ~/.local/share/opencode/auth.json)
opencode auth logoutremove a stored credential
Your setup uses env vars, not auth login. $DEEPSEEK_API_KEY comes from the 1Password "Bash Secrets" item; rotate with load_secrets refresh.

Models & usage

opencode modelsevery model in opencode's catalogue
opencode models deepseekfiltered by provider
opencode statstoken totals + estimated cost across all sessions

Sessions

opencode sessionshow session subcommands
opencode session listevery saved session (id, title, dir, last used)
opencode export <sessionID>dump a session to JSON
opencode import <file|url>load a session from JSON

Plugins, MCP, agents

opencode plugin <module>install a JS plugin and add to config
opencode mcpmanage MCP server connections
opencode agentmanage agent definitions
opencode acpstart the Agent Client Protocol server (for IDE integrations)
opencode serveheadless server (REST API on :4096)
opencode webserve + open a browser TUI
opencode attach URLconnect to a running headless server

GitHub & PRs

opencode githubmanage the GitHub-action agent
opencode pr <number>checkout PR branch then launch opencode in it — great for review
Maintenance: opencode upgrade pulls the latest. opencode uninstall removes everything.
Config lives at ~/.config/opencode/opencode.jsonc (project-level overrides go in ./opencode.jsonc at the repo root). JSONC means JSON-with-comments. Schema is at https://opencode.ai/config.json.

Your current config

{
  "$schema": "https://opencode.ai/config.json",
  "model":       "deepseek/deepseek-v4-pro",
  "small_model": "deepseek/deepseek-chat"
}
model is the primary brain. small_model is used for cheap background work: session title generation, summarisation during compaction, search query rewriting.

Common top-level fields

modelprovider/model (e.g. deepseek/deepseek-chat)
small_modelcheap model for background tasks
themeTUI colour theme name
autosharetrue/false — auto-publish sessions to web
autoupdatebackground self-update
instructionsarray of file paths to inject as system context (e.g. ["AGENTS.md", "CLAUDE.md"])
experimentalfeature flags

Per-agent overrides

{
  "agent": {
    "build": { "model": "deepseek/deepseek-v4-pro" },
    "plan":  { "model": "deepseek/deepseek-reasoner" }
  }
}
Built-in agents: build (default, has all tools), plan (read-only, drafts plans), general (Q&A). Define custom agents under agent.<name> with their own tools + model.

Tool permissions

{
  "permission": {
    "edit":  "ask",
    "bash":  "ask",
    "webfetch": "allow"
  }
}
allowrun without prompting
askprompt every time (default for risky tools)
denyblock entirely
Granular patterns: "bash": { "rm *": "deny", "*": "ask" }

MCP servers

{
  "mcp": {
    "playwright": {
      "type": "local",
      "command": ["npx", "-y",
                  "@playwright/mcp@latest"],
      "enabled": true
    },
    "linear": {
      "type": "remote",
      "url": "https://mcp.linear.app/sse"
    }
  }
}
opencode speaks MCP natively. Any tool you'd give Claude Code via ~/.claude/mcp.json works here too — including your Jira, Confluence, Datadog, Postgres servers.

Custom slash commands

{
  "command": {
    "review": {
      "description": "review staged changes",
      "prompt": "Review `git diff --staged` for bugs, security, and style.",
      "agent": "build"
    }
  }
}
Trigger from the TUI input as /review. Commands can also live as files under ~/.config/opencode/commands/ — the filename becomes the command name.
Your provider is deepseek (env: $DEEPSEEK_API_KEY). opencode's catalogue exposes the four DeepSeek model IDs below. All four route to https://api.deepseek.com.

The four DeepSeek IDs

deepseek/deepseek-v4-prostrongest general-purpose — your default. Best for coding & agentic work.
deepseek/deepseek-v4-flashfast & cheap — quick edits, summaries, your small_model upgrade pick
deepseek/deepseek-chatlegacy chat model (V3-line). Always available, safe fallback if v4 errors.
deepseek/deepseek-reasonerextended thinking (R1-line). Slower, deeper. Pick for plans & architecture.
If deepseek-v4-pro returns 404 against your API tier, fall back to deepseek-chat until the tier upgrades.

Picking the right one

Refactor / multi-file editv4-pro
Quick "rename this" / explainv4-flash
Plan a feature from scratchreasoner
Session titles, compactionchat (cheapest) — small_model
Switch on the fly in the TUI with <leader>m. The new model applies from the next turn.

Where the bill comes from

DeepSeek charges per million tokens (input / output). Pricing changes — check api-docs.deepseek.com/pricing. Off-peak hours (16:30–00:30 UTC) get a steep discount on V3 chat.

ModelInputOutput
deepseek-chat~$0.27/M~$1.10/M
deepseek-reasoner~$0.55/M~$2.19/M
deepseek-v4-provariesvaries
Check actual spend with opencode stats. Balance with curl -H "Authorization: Bearer $DEEPSEEK_API_KEY" https://api.deepseek.com/user/balance.

Other providers you could add

Set the relevant env var and opencode auto-detects:

$ANTHROPIC_API_KEYClaude (Opus 4.7, Sonnet 4.6, Haiku 4.5)
$OPENAI_API_KEYOpenAI & o-series
$OPENROUTER_API_KEYOpenRouter (300+ models, one bill)
$GROQ_API_KEYGroq (very fast Llama / Mixtral)
(none)Ollama / LM Studio / any local OpenAI-compatible server — configure under provider.
Per-task model swap: opencode run -m anthropic/claude-sonnet-4-6 "...".

Local model recipe

{
  "provider": {
    "ollama": {
      "npm": "@ai-sdk/openai-compatible",
      "options": {
        "baseURL": "http://localhost:11434/v1"
      },
      "models": {
        "qwen2.5-coder:32b": {}
      }
    }
  },
  "model": "ollama/qwen2.5-coder:32b"
}
Useful when you need privacy or you're offline — but local models still lag DeepSeek-v4 by a wide margin on agentic tasks.

Per-agent model strategy

Best-of-both: a cheap fast model for chat, a deep reasoner for planning.

{
  "model": "deepseek/deepseek-v4-pro",
  "small_model": "deepseek/deepseek-v4-flash",
  "agent": {
    "plan": { "model": "deepseek/deepseek-reasoner" }
  }
}