Skip to content

Themes

pi can create themes. Ask it to build one for your setup.

Themes are JSON files that define colors for the TUI.

Pi loads themes from:

  • Built-in: dark, light
  • Global: ~/.pi/agent/themes/*.json
  • Project: .pi/themes/*.json (only after the project is trusted)
  • Packages: themes/ directories or pi.themes entries in package.json
  • Settings: themes array with files or directories
  • CLI: --theme <path> (repeatable)

Disable discovery with --no-themes.

Select a theme via /settings or in settings.json:

{
"theme": "my-theme"
}

On first run, pi detects your terminal background and defaults to dark or light.

  1. Create a theme file:
Terminal window
mkdir -p ~/.pi/agent/themes
vim ~/.pi/agent/themes/my-theme.json
  1. Define the theme with all required colors (see Color Tokens):
{
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"name": "my-theme",
"vars": {
"primary": "#00aaff",
"secondary": 242
},
"colors": {
"accent": "primary",
"border": "primary",
"borderAccent": "#00ffff",
"borderMuted": "secondary",
"success": "#00ff00",
"error": "#ff0000",
"warning": "#ffff00",
"muted": "secondary",
"dim": 240,
"text": "",
"thinkingText": "secondary",
"selectedBg": "#2d2d30",
"userMessageBg": "#2d2d30",
"userMessageText": "",
"customMessageBg": "#2d2d30",
"customMessageText": "",
"customMessageLabel": "primary",
"toolPendingBg": "#1e1e2e",
"toolSuccessBg": "#1e2e1e",
"toolErrorBg": "#2e1e1e",
"toolTitle": "primary",
"toolOutput": "",
"mdHeading": "#ffaa00",
"mdLink": "primary",
"mdLinkUrl": "secondary",
"mdCode": "#00ffff",
"mdCodeBlock": "",
"mdCodeBlockBorder": "secondary",
"mdQuote": "secondary",
"mdQuoteBorder": "secondary",
"mdHr": "secondary",
"mdListBullet": "#00ffff",
"toolDiffAdded": "#00ff00",
"toolDiffRemoved": "#ff0000",
"toolDiffContext": "secondary",
"syntaxComment": "secondary",
"syntaxKeyword": "primary",
"syntaxFunction": "#00aaff",
"syntaxVariable": "#ffaa00",
"syntaxString": "#00ff00",
"syntaxNumber": "#ff00ff",
"syntaxType": "#00aaff",
"syntaxOperator": "primary",
"syntaxPunctuation": "secondary",
"thinkingOff": "secondary",
"thinkingMinimal": "primary",
"thinkingLow": "#00aaff",
"thinkingMedium": "#00ffff",
"thinkingHigh": "#ff00ff",
"thinkingXhigh": "#ff0000",
"bashMode": "#ffaa00"
}
}
  1. Select the theme via /settings.

Hot reload: When you edit the currently active custom theme file, pi reloads it automatically for immediate visual feedback.

{
"$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"name": "my-theme",
"vars": {
"blue": "#0066cc",
"gray": 242
},
"colors": {
"accent": "blue",
"muted": "gray",
"text": "",
...
}
}
  • name is required, must be unique, and must not contain /.
  • vars is optional. Define reusable colors here, then reference them in colors.
  • colors must define all 51 required tokens.

The $schema field enables editor auto-completion and validation.

Every theme must define all 51 color tokens. There are no optional colors.

TokenPurpose
accentPrimary accent (logo, selected items, cursor)
borderNormal borders
borderAccentHighlighted borders
borderMutedSubtle borders (editor)
successSuccess states
errorError states
warningWarning states
mutedSecondary text
dimTertiary text
textDefault text (usually "")
thinkingTextThinking block text
TokenPurpose
selectedBgSelected line background
userMessageBgUser message background
userMessageTextUser message text
customMessageBgExtension message background
customMessageTextExtension message text
customMessageLabelExtension message label
toolPendingBgTool box (pending)
toolSuccessBgTool box (success)
toolErrorBgTool box (error)
toolTitleTool title
toolOutputTool output text
TokenPurpose
mdHeadingHeadings
mdLinkLink text
mdLinkUrlLink URL
mdCodeInline code
mdCodeBlockCode block content
mdCodeBlockBorderCode block fences
mdQuoteBlockquote text
mdQuoteBorderBlockquote border
mdHrHorizontal rule
mdListBulletList bullets
TokenPurpose
toolDiffAddedAdded lines
toolDiffRemovedRemoved lines
toolDiffContextContext lines
TokenPurpose
syntaxCommentComments
syntaxKeywordKeywords
syntaxFunctionFunction names
syntaxVariableVariables
syntaxStringStrings
syntaxNumberNumbers
syntaxTypeTypes
syntaxOperatorOperators
syntaxPunctuationPunctuation

Editor border colors indicating thinking level (visual hierarchy from subtle to prominent):

TokenPurpose
thinkingOffThinking off
thinkingMinimalMinimal thinking
thinkingLowLow thinking
thinkingMediumMedium thinking
thinkingHighHigh thinking
thinkingXhighExtra high thinking
TokenPurpose
bashModeEditor border in bash mode (! prefix)

The export section controls colors for /export HTML output. If omitted, colors are derived from userMessageBg.

{
"export": {
"pageBg": "#18181e",
"cardBg": "#1e1e24",
"infoBg": "#3c3728"
}
}

Four formats are supported:

FormatExampleDescription
Hex"#ff0000"6-digit hex RGB
256-color39xterm 256-color palette index (0-255)
Variable"primary"Reference to a vars entry
Default""Terminal’s default color
  • 0-15: Basic ANSI colors (terminal-dependent)
  • 16-231: 6×6×6 RGB cube (16 + 36×R + 6×G + B where R,G,B are 0-5)
  • 232-255: Grayscale ramp

Pi uses 24-bit RGB colors. Most modern terminals support this (iTerm2, Kitty, WezTerm, Windows Terminal, VS Code). For older terminals with only 256-color support, pi falls back to the nearest approximation.

Check truecolor support:

Terminal window
echo $COLORTERM # Should output "truecolor" or "24bit"

Dark terminals: Use bright, saturated colors with higher contrast.

Light terminals: Use darker, muted colors with lower contrast.

Color harmony: Start with a base palette (Nord, Gruvbox, Tokyo Night), define it in vars, and reference consistently.

Testing: Check your theme with different message types, tool states, markdown content, and long wrapped text.

VS Code: Set terminal.integrated.minimumContrastRatio to 1 for accurate colors.

See the built-in themes: