> ## Documentation Index
> Fetch the complete documentation index at: https://v2.opencode.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Themes

> Choose a built-in TUI theme or create a custom color scheme.

OpenCode includes built-in light and dark themes and can load custom themes
from your global configuration or a project directory. The default theme is
`opencode`.

## Choose a theme

In the full-screen TUI, run:

```text theme={null}
/themes
```

You can also open the picker with `ctrl+x`, then `t`, using the
default keybindings.

Use `/settings` to change both the theme and its color mode. OpenCode supports
three modes:

| Mode     | Behavior                                                 |
| -------- | -------------------------------------------------------- |
| `system` | Follow the terminal's detected light or dark appearance. |
| `dark`   | Always use the theme's dark colors.                      |
| `light`  | Always use the theme's light colors.                     |

Your selection is stored in `~/.config/opencode/cli.json`, or the equivalent
path under `$XDG_CONFIG_HOME`:

```json title="cli.json" theme={null}
{
  "theme": {
    "name": "tokyonight",
    "mode": "system"
  }
}
```

<Note>
  Theme selection applies to the full-screen TUI. Direct interactive runs use colors derived from the terminal palette
  and honor only the color mode.
</Note>

## Built-in themes

OpenCode currently includes:

|              |                     |                        |
| ------------ | ------------------- | ---------------------- |
| `aura`       | `ayu`               | `carbonfox`            |
| `catppuccin` | `catppuccin-frappe` | `catppuccin-macchiato` |
| `cobalt2`    | `cursor`            | `dracula`              |
| `everforest` | `flexoki`           | `github`               |
| `gruvbox`    | `kanagawa`          | `lucent-orng`          |
| `material`   | `matrix`            | `mercury`              |
| `monokai`    | `nightowl`          | `nord`                 |
| `one-dark`   | `opencode`          | `orng`                 |
| `osaka-jade` | `palenight`         | `rosepine`             |
| `solarized`  | `synthwave84`       | `tokyonight`           |
| `vercel`     | `vesper`            | `zenburn`              |

When OpenCode can read your terminal palette, the picker also includes
`system`. The `system` theme generates its colors from your terminal's
foreground, background, and ANSI palette.

## Custom themes

Create a JSON file in either of these locations:

```text theme={null}
~/.config/opencode/themes/my-theme.json
.opencode/themes/my-theme.json
```

OpenCode checks the global theme directory first, followed by every
`.opencode/themes` directory from the filesystem root down to the current
directory. A more local file with the same filename overrides an earlier one.
The filename becomes the theme name, so `my-theme.json` appears as `my-theme`.

Custom theme files must be strict JSON. Comments and trailing commas are not
supported.

### Format

V2 themes organize colors into hue scales and semantic tokens. Set `version`
to `2` and define at least one of `light` or `dark`:

<Warning>
  Native V2 custom theme files are not loaded directly by the current beta. Existing custom files use the V1 format and
  are migrated to these tokens at runtime. This reference tracks the native V2 schema while direct file loading is
  completed.
</Warning>

By default, a theme inherits OpenCode's complete theme, so you only need to
define overrides. Set `mergeMode` to `true` to inherit one mode from the other
before applying that mode's overrides. Set `standalone` to `true` only when you
intend to supply a complete independent theme.

Each token accepts:

* A hex color such as `"#5c9cf5"`
* `"transparent"` to use the terminal default
* A hue reference such as `"$hue.blue.500"`
* Another semantic token reference such as `"$text.default"`

Syntax and markdown tokens accept hex colors and hue references. Other
semantic tokens can reference any semantic token.

```json title="my-theme.json" theme={null}
{
  "version": 2,
  "light": {
    "hue": {
      "accent": "$hue.purple",
      "interactive": "$hue.purple"
    },
    "text": {
      "default": "$hue.neutral.900"
    },
    "background": {
      "default": "#fafafa"
    }
  },
  "dark": {
    "mergeMode": true,
    "text": {
      "default": "$hue.neutral.100"
    },
    "background": {
      "default": "#101014"
    }
  }
}
```

## Token reference

This reference is generated from the Effect schema in
`packages/tui/src/theme/v2/schema.ts`. Changes to the runtime schema update
this section through `bun run generate`.

### Hue tokens

Every hue is a 9-step scale. Define a scale with all of these
steps, or alias it to another hue with a value such as `$hue.blue`.

|       | Values                                                                                                   |
| ----- | -------------------------------------------------------------------------------------------------------- |
| Hues  | `gray`, `red`, `orange`, `yellow`, `green`, `cyan`, `blue`, `purple`, `accent`, `interactive`, `neutral` |
| Steps | `100`, `200`, `300`, `400`, `500`, `600`, `700`, `800`, `900`                                            |

Reference a hue color as `$hue.<name>.<step>`, for example
`$hue.interactive.500`.

### Semantic tokens

Semantic values can reference another token by prefixing its path with `$`,
for example `$text.default`. Stateful tokens inherit their `default`
value when a state is omitted.

| Group                  | Tokens                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `text`                 | `text.default`<br />`text.subdued`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `text.action`          | `text.action.primary.default`<br />`text.action.primary.$hovered`<br />`text.action.primary.$focused`<br />`text.action.primary.$pressed`<br />`text.action.primary.$selected`<br />`text.action.primary.$disabled`<br />`text.action.destructive.default`<br />`text.action.destructive.$hovered`<br />`text.action.destructive.$focused`<br />`text.action.destructive.$pressed`<br />`text.action.destructive.$selected`<br />`text.action.destructive.$disabled`                                                                         |
| `text.formfield`       | `text.formfield.default`<br />`text.formfield.$hovered`<br />`text.formfield.$focused`<br />`text.formfield.$pressed`<br />`text.formfield.$selected`<br />`text.formfield.$disabled`                                                                                                                                                                                                                                                                                                                                                        |
| `text.feedback`        | `text.feedback.error.default`<br />`text.feedback.error.subdued`<br />`text.feedback.warning.default`<br />`text.feedback.warning.subdued`<br />`text.feedback.success.default`<br />`text.feedback.success.subdued`<br />`text.feedback.info.default`<br />`text.feedback.info.subdued`                                                                                                                                                                                                                                                     |
| `background`           | `background.default`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `background.surface`   | `background.surface.offset`<br />`background.surface.overlay`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `background.action`    | `background.action.primary.default`<br />`background.action.primary.$hovered`<br />`background.action.primary.$focused`<br />`background.action.primary.$pressed`<br />`background.action.primary.$selected`<br />`background.action.primary.$disabled`<br />`background.action.destructive.default`<br />`background.action.destructive.$hovered`<br />`background.action.destructive.$focused`<br />`background.action.destructive.$pressed`<br />`background.action.destructive.$selected`<br />`background.action.destructive.$disabled` |
| `background.formfield` | `background.formfield.default`<br />`background.formfield.$hovered`<br />`background.formfield.$focused`<br />`background.formfield.$pressed`<br />`background.formfield.$selected`<br />`background.formfield.$disabled`                                                                                                                                                                                                                                                                                                                    |
| `background.feedback`  | `background.feedback.error.default`<br />`background.feedback.warning.default`<br />`background.feedback.success.default`<br />`background.feedback.info.default`                                                                                                                                                                                                                                                                                                                                                                            |
| `border`               | `border.default`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `scrollbar`            | `scrollbar.default`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `diff.text`            | `diff.text.added`<br />`diff.text.removed`<br />`diff.text.context`<br />`diff.text.hunkHeader`                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `diff.background`      | `diff.background.added`<br />`diff.background.removed`<br />`diff.background.context`                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `diff.highlight`       | `diff.highlight.added`<br />`diff.highlight.removed`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `diff.lineNumber`      | `diff.lineNumber.text`<br />`diff.lineNumber.background.added`<br />`diff.lineNumber.background.removed`                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `syntax`               | `syntax.comment`<br />`syntax.keyword`<br />`syntax.function`<br />`syntax.variable`<br />`syntax.string`<br />`syntax.number`<br />`syntax.type`<br />`syntax.operator`<br />`syntax.punctuation`                                                                                                                                                                                                                                                                                                                                           |
| `markdown`             | `markdown.text`<br />`markdown.heading`<br />`markdown.link`<br />`markdown.linkText`<br />`markdown.code`<br />`markdown.blockQuote`<br />`markdown.emphasis`<br />`markdown.strong`<br />`markdown.horizontalRule`<br />`markdown.listItem`<br />`markdown.listEnumeration`<br />`markdown.image`<br />`markdown.imageText`<br />`markdown.codeBlock`                                                                                                                                                                                      |

### Contexts

`@context:elevated` and `@context:overlay` accept partial
overrides of the semantic tokens above. Components apply these contexts to
surfaces that need different contrast without changing the base theme.

If you add or edit a custom theme while OpenCode is running, restart the TUI to
reload it.

## Terminal colors

Themes display most accurately in a terminal with truecolor support. Check
your terminal with:

```bash theme={null}
echo $COLORTERM
```

Most modern terminals report `truecolor` or `24bit`. Without truecolor,
OpenCode approximates theme colors using the available terminal palette.
