# How to Add Custom Themes to the kimi-code Terminal UI

> Learn how to add custom themes to the kimi-code terminal UI. Create JSON files to define color overrides and activate your themes easily. Personalize your terminal experience today.

- Repository: [Moonshot AI/kimi-code](https://github.com/MoonshotAI/kimi-code)
- Tags: how-to-guide
- Published: 2026-07-25

---

**You can add custom themes to the kimi-code terminal UI by creating JSON files in `~/.kimi-code/themes/` that define color overrides on top of the built-in dark or light palettes, then activating them via the `/theme <name>` slash command or the `theme` setting in [`tui.toml`](https://github.com/MoonshotAI/kimi-code/blob/main/tui.toml).**

The MoonshotAI/kimi-code terminal interface supports user-defined color schemes that extend the built-in styling system. By placing properly structured theme files in the custom themes directory, you can personalize the TUI with persistent color palettes that merge seamlessly with the base dark or light modes.

## Custom Theme Storage Location

Custom themes reside in the user data directory under the `themes` subdirectory. According to the source code in [`apps/kimi-code/src/tui/theme/custom-theme-loader.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/src/tui/theme/custom-theme-loader.ts), the function `getCustomThemesDir()` returns `join(getDataDir(), 'themes')`, which resolves to `~/.kimi-code/themes/` on most systems.

Each theme is a standalone JSON file named `<theme-name>.json`. The loader exposes two functions for enumeration: `listCustomThemes()` (async) and `listCustomThemesSync()` (sync), which read directory entries, strip the `.json` suffix, and filter out reserved names. These reserved names—`dark`, `light`, and `auto`—cannot be used for custom themes, preventing accidental overrides of built-in palettes.

## Creating a Valid Theme File

Theme files must conform to the `CustomThemeSchema` (a Zod schema) defined in the loader. A valid custom theme JSON structure includes:

- **name**: Internal identifier matching the filename (without extension)
- **displayName**: Human-readable label shown in the UI
- **base**: Either `"dark"` or `"light"`—determines which built-in palette serves as the foundation
- **colors**: An object mapping token names to hex color strings

The `readCustomTheme(name)` function validates all color values against the regex `^#[0-9a-fA-F]{6}$`. Invalid hex strings are silently ignored, causing those tokens to fall back to the base palette values.

Create a file at `~/.kimi-code/themes/rose.json`:

```json
{
  "name": "rose",
  "displayName": "Rosy Dawn",
  "base": "light",
  "colors": {
    "background": "#fff1f0",
    "foreground": "#5a2120",
    "accent": "#d23669",
    "warning": "#e06c75"
  }
}

```

If you omit the `base` field, the loader defaults to `"dark"` when merging colors.

## Loading and Merging Custom Themes

The `loadCustomThemeMerged(name)` function in [`custom-theme-loader.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/custom-theme-loader.ts) orchestrates theme application. It first calls `readCustomTheme(name)` to parse and validate the JSON, then retrieves the base palette via `getBuiltInPalette(parsed.base)` from [`src/tui/theme/colors.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/src/tui/theme/colors.ts). The final color set is created by spreading the base palette and overwriting specific keys with your custom values.

You can load themes programmatically using the loader API:

```typescript
import { loadCustomThemeMerged } from '#/tui/theme/custom-theme-loader';

async function apply(name: string) {
  const palette = await loadCustomThemeMerged(name);
  if (!palette) {
    console.error(`Theme ${name} not found`);
    return;
  }
  // palette is a complete ColorPalette object ready for the UI renderer
  console.log('Loaded palette:', palette);
}

apply('rose');

```

To enumerate available custom themes from external scripts:

```typescript
import { listCustomThemes } from '#/tui/theme/custom-theme-loader';

async function showThemes() {
  const themes = await listCustomThemes();
  console.log('Custom themes:', themes); // e.g., ["rose", "midnight"]
}

showThemes();

```

## Activating Themes in the Terminal UI

Once a theme file exists in `~/.kimi-code/themes/`, you can activate it immediately without restarting the application. The TUI driver implements the slash command `/theme <name>` in [`src/tui/commands/theme.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/src/tui/commands/theme.ts), which invokes `loadCustomThemeMerged(name)` and updates `appState.theme` instantly.

Type the following inside the running kimi-code interface:

```

/theme rose

```

For persistent configuration across sessions, set the theme in `~/.kimi-code/tui.toml`:

```toml
theme = "rose"

```

When the config parser reads [`tui.toml`](https://github.com/MoonshotAI/kimi-code/blob/main/tui.toml) at startup, it stores the value in `appState.theme` before rendering begins. If you set `theme = "auto"`, the system uses [`src/tui/utils/terminal-theme.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/src/tui/utils/terminal-theme.ts) to watch for OSC 11 background-color reports from the terminal and automatically switches between built-in dark and light palettes based on the detected background luminance.

## Summary

- **Storage location**: Place JSON theme files in `~/.kimi-code/themes/`; the loader uses `getCustomThemesDir()` to locate this path.
- **File format**: Valid themes match `CustomThemeSchema` with a `base` palette (dark/light) and hex colors validated by `^#[0-9a-fA-F]{6}$`.
- **Reserved names**: You cannot name themes `dark`, `light`, or `auto`, as these are protected built-in identifiers.
- **Activation**: Use the `/theme <name>` command for immediate switching or set `theme = "<name>"` in [`tui.toml`](https://github.com/MoonshotAI/kimi-code/blob/main/tui.toml) for persistence.
- **Merge behavior**: `loadCustomThemeMerged()` spreads your custom colors over the built-in base palette, with invalid colors falling back to defaults.

## Frequently Asked Questions

### What is the exact file format for kimi-code custom themes?

Custom themes are JSON files that conform to the `CustomThemeSchema` defined in [`apps/kimi-code/src/tui/theme/custom-theme-loader.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/src/tui/theme/custom-theme-loader.ts). They must include `name`, `displayName`, a `base` palette selector (`"dark"` or `"light"`), and a `colors` object containing valid 6-digit hex codes. The `readCustomTheme()` function validates these files using Zod and filters out malformed color strings.

### Why can't I name my custom theme "dark" or "light"?

The names `dark`, `light`, and `auto` are reserved by the theme system to protect the built-in palettes and the automatic detection mode. The `listCustomThemes()` and `listCustomThemesSync()` functions explicitly filter out these reserved strings when enumerating available themes, ensuring users cannot accidentally override critical system themes.

### How does kimi-code handle invalid color values in theme files?

When `readCustomTheme()` parses a theme file, it validates each color string against the regex `^#[0-9a-fA-F]{6}$`. Invalid hex codes are silently discarded during the merge process, causing those specific UI tokens to inherit colors from the base palette (dark or light) rather than crashing the loader or displaying errors.

### Can I switch themes dynamically without restarting the terminal UI?

Yes. The TUI supports runtime theme switching through the `/theme <name>` slash command implemented in [`src/tui/commands/theme.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/src/tui/commands/theme.ts). This command calls `loadCustomThemeMerged()` and updates `appState.theme` immediately, refreshing the interface without requiring a restart. For automatic switching based on terminal background color, set `theme = "auto"` in [`tui.toml`](https://github.com/MoonshotAI/kimi-code/blob/main/tui.toml) to enable OSC 11 detection via [`src/tui/utils/terminal-theme.ts`](https://github.com/MoonshotAI/kimi-code/blob/main/src/tui/utils/terminal-theme.ts).