A small OpenCode TUI plugin that adds a /stats command showing per-session
token usage (input, output, reasoning, cache read/write) and live generation
speed in tok/s.
The entire plugin was written (vibe coded) and debugged with OpenCode itself.
/statsopens a popup (dialog) with a token breakdown for the current session:- Input (prompt), Output (completion), Reasoning
- Cache read, Cache write
Total(input + output + reasoning, cache excluded — cache tokens are priced differently)Total (incl. cache)(all token categories summed)Generation speed (last request)in tok/s- A note that the data comes from OpenCode's own token reporting.
- Live tok/s is rendered in the prompt bar (the
session_prompt_rightslot, next to the model/context area) after each request completes. - All data is taken from OpenCode's internal reporting; accuracy depends on the
provider's usage metadata (e.g. reasoning/cache are
0when the model or provider does not report them).
- It is a TUI plugin (
@opencode-ai/plugin/tui), not a server plugin. Server slash commands always trigger a model turn, so a popup requires the TUI plugin API (api.keymap.registerLayerwithslashName: "stats"→ opensapi.ui.dialog.replace(...)). - Token counts are read from each assistant message's
info.tokens({ total, input, output, reasoning, cache: { read, write } }), which OpenCode exposes onmessage.updatedevents. The plugin accumulates these per session (keyed bymessageIDto avoid double counting) and recomputes totals. The/statsdialog prefers a snapshot fromapi.client.session.messages, falling back to the event-accumulated totals. - Generation speed is computed from the finished message's
time.completed - time.createddivided by its output token count. - The tok/s readout is shown via the
session_prompt_rightslot.
stats.tui.tsx— the plugin (default export{ id, tui }).tui.json— TUI config snippet that registers the plugin.package.json— the dependencies the plugin imports.
-
Locate your OpenCode config directory. This is the directory OpenCode actually reads — by default on Linux/WSL
~/.config/opencode. Project-level config can also live in.opencode/inside a repo. -
Copy the plugin into the plugins folder of that config dir:
mkdir -p ~/.config/opencode/plugins cp stats.tui.tsx ~/.config/opencode/plugins/stats.tui.tsx
-
Register it in
tui.json(create or merge with the existing file in the config dir):{ "$schema": "https://opencode.ai/tui.json", "plugin": ["./plugins/stats.tui.tsx"] } -
Install the dependencies. The plugin imports
@opencode-ai/plugin/tui,@opentui/solid, andsolid-js. Add them to the config dir'spackage.json(OpenCode runs an install step on it at startup), then install:# in the config dir (~/.config/opencode) cat package.json # should list the three deps below npm install # or let OpenCode's own startup install run
Required dependencies:
{ "dependencies": { "@opencode-ai/plugin": "1.18.16", "@opentui/solid": "0.4.5", "solid-js": "^1.9.12" } } -
Restart OpenCode. Type
/statsto open the popup. The tok/s readout appears in the prompt bar after a request completes.
- TUI plugins are not auto-discovered; they must be listed in
tui.json. - This plugin is fully separate from the OpenCode binary (loaded via config), so it survives OpenCode updates.
- If the popup shows "not measured yet", generate at least one request first so
message.updatedevents populate the totals.