Creating Custom Themes for Tempest
Tempest’s theming system is built on JSON-based theme files that define colors for every UI element. This guide walks you through creating a custom theme from scratch, loading it into Tempest, and distributing it.Theme Anatomy
A Tempest theme is a JSON file with three top-level fields:| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Display name of the theme (shown in theme switcher) |
type | ”dark” or “light” | Yes | Theme classification, affects user expectations and accent contrast |
colors | object | Yes | Object mapping token names to hex color values |
Color Tokens
A theme defines colors using dot-notation token names. These are automatically converted to CSS variables with the pattern--tempest-TOKEN-CONVERTED.
For example:
bg.basebecomes--tempest-bg-baseaccent.bluebecomes--tempest-accent-bluesyntax.keywordbecomes--tempest-syntax-keyword
Required Token Groups
Every theme must define colors for these token groups. Omitting a group will cause theme loading to fail. Background tokens (bg.* - 10 required):bg.base- Root background, main containerbg.editor- Code editor/main work areabg.sidebar- Navigation sidebarbg.panel- Panels and dropdownsbg.titlebar- Window titlebarbg.hover- Hover state backgroundsbg.active- Selected/active state backgroundsbg.input- Input field backgroundsbg.selection- Text selection backgroundbg.selection-focused- Focused text selection
fg.default- Primary textfg.muted- Secondary/disabled textfg.subtle- Tertiary text, placeholders
border.default- Standard bordersborder.subtle- Secondary borders, dividers
accent.blue- Primary accent/linksaccent.pink- Secondary accentaccent.green- Success statesaccent.yellow- Warningsaccent.purple- Tertiary accentaccent.cyan- Additional accentaccent.red- Errors, destructive actions
syntax.comment- Code commentssyntax.keyword- Language keywordssyntax.string- String literalssyntax.function- Function namessyntax.variable- Variables/identifierssyntax.constant- Constants/numberssyntax.type- Type annotationssyntax.operator- Operatorssyntax.attribute- Attributes/decorators
git.added- New/added filesgit.modified- Modified filesgit.deleted- Deleted filesgit.conflict- Merge conflictsgit.ignored- Ignored filesgit.untracked- Untracked files
island.bg-closed- Collapsed panel backgroundisland.border-closed- Collapsed panel borderisland.bg-open- Expanded panel backgroundisland.border-open- Expanded panel border
tooltip.bg- Tooltip backgroundtooltip.fg- Tooltip text
semantic.error- Error messagessemantic.warning- Warningssemantic.info- Informationsemantic.success- Success states
terminal.fg- Terminal foreground textterminal.selection- Terminal selection backgroundterminal.black- ANSI color 0terminal.red- ANSI color 1terminal.green- ANSI color 2terminal.yellow- ANSI color 3terminal.blue- ANSI color 4terminal.purple- ANSI color 5 (magenta)terminal.cyan- ANSI color 6terminal.white- ANSI color 7terminal.brightBlack- ANSI color 8terminal.brightRed- ANSI color 9terminal.brightGreen- ANSI color 10terminal.brightYellow- ANSI color 11terminal.brightBlue- ANSI color 12terminal.brightPurple- ANSI color 13terminal.brightCyan- ANSI color 14terminal.brightWhite- ANSI color 15
Step-by-Step Theme Creation
Step 1: Start with a Base
Copy an existing theme as your starting point. This ensures you have all required tokens:Step 2: Customize Colors
Replace the hex color values with your chosen colors. Keep these considerations in mind: Contrast ratios: Ensure sufficient contrast between text and backgrounds for accessibility.- Use an online contrast checker tool
- Aim for at least WCAG AA compliance (4.5:1 for normal text)
fg.defaultshould be your primary/brightest textfg.mutedshould be noticeably dimmerfg.subtleshould be even more subdued
#ffffff1a= white at 10.2% opacity#ffffff22= white at 13.3% opacity#0000001a= black at 10.2% opacity
Step 3: Validate Your Theme
Check that:- All 65 required tokens are present
- All values are valid hex colors (6 hex digits with optional alpha channel)
- No typos in token names
- Contrasts are sufficient for readability
Step 4: Load the Theme into Tempest
There are two ways to load your custom theme:Option A: Programmatic Loading via loadThemeFromJson()
The Tempest theme system exposes a loadThemeFromJson() function that accepts a JSON string:
loadThemeFromJson() logs an error to the console and does not apply the theme.
Option B: Bundle as a Built-in Theme
To include a theme in the Tempest application directly:-
Create a directory under
src/themes/: -
Place your
theme.jsonfile in that directory -
Rebuild Tempest:
- Your theme will automatically appear in the theme switcher, and the app will remember the user’s selection via localStorage
Theme Distribution and Sharing
As a JSON File
Share your theme as a standalone JSON file. Users can:- Copy the JSON into a text file or editor
- Load it via the theme loading mechanism in Tempest
- The app persists their choice in localStorage
As Part of a Theme Package
You can create a more formal theme package:Best Practices for Theme Design
Color Consistency
Reuse accent colors across related UI elements. For example, all git status indicators should use the git.* tokens consistently.Dark Theme Guidelines
For dark themes:- Use very dark backgrounds (near black) for editor areas:
#0a0a0ato#1a1a1a - Lighter backgrounds for UI chrome: slightly lighter than editor
- Text should be bright and high-contrast:
#e0e0e0to#ffffff - Use subtle alpha-based overlays for hover states:
#ffffff1ato#ffffff22
Light Theme Guidelines
For light themes:- Use very light backgrounds (near white) for editor areas:
#ffffffto#fafafa - Slightly darker backgrounds for UI chrome:
#fafafaor#f5f5f5 - Text should be dark and readable:
#1a1a1ato#333333 - Use subtle alpha-based overlays for hover states:
#0000001ato#00000022
Accent Color Selection
Choose accent colors that:- Stand out clearly against your theme’s backgrounds
- Have semantic meaning (blue for primary/links, green for success, red for errors)
- Work well in both 100% opacity and semi-transparent contexts
Terminal Color Palette
Terminal colors should follow standard ANSI conventions:- Black/white are for standard terminal foreground/background
- Colors 1-7 are the normal ANSI colors
- Colors 8-15 are the bright variants (typically brighter versions of 1-7)
Syntax Highlighting Coherence
Syntax token colors should reflect code semantics:- Keywords (control flow) often match accent.pink or accent.red
- Strings typically use a green or yellow tone
- Functions/classes often use purple or blue
- Comments should be distinctly muted compared to code
Testing Your Theme
In the Browser
- Create a simple test HTML file that loads Tempest with your theme:
- Open the file in a browser and verify colors look good
In Tempest Itself
- Use the
loadThemeFromJson()function in Tempest - Navigate through different views (sidebar, editor, terminal, dialogs)
- Test interactive states (hover, focus, active)
- Verify syntax highlighting in code
- Check git status colors in file lists
- Test terminal output with colored text
Accessibility Checks
Use an online contrast checker tool to verify:- Text on backgrounds meets WCAG AA (4.5:1 minimum)
- Interactive elements are clearly distinguishable
- Colorblind users can still understand status indicators (don’t rely on color alone)
Common Theme Patterns
Monochromatic Theme
Use variations of a single hue for backgrounds and text:Vibrant/Neon Theme
Use bright, saturated colors:High Contrast Theme
Maximize contrast for accessibility:Warm Tones Theme
Use browns, oranges, and warm accent colors:Troubleshooting
Theme won’t load
- Check JSON syntax with an online JSON validator
- Verify all 65 required tokens are present
- Check that all color values are valid hex strings
- Look for console errors in browser DevTools
Colors look washed out
- Increase contrast between foreground and background colors
- Make accent colors more saturated
- Reduce opacity on overlay colors (
#ffffff1a->#ffffff2e)
Text is hard to read
- Increase the lightness/brightness difference between
fg.defaultandbg.base - Use contrast checker tools
- Test with multiple font sizes and distances
Theme persists between theme switches
This is expected behavior. Tempest stores the selected theme in localStorage. To reset, use your browser’s developer tools to clear thetempest-theme key from localStorage.
Sharing Your Theme
Once you are happy with your theme:- Save as
MyThemeName.json - Share via:
- GitHub Gist or repository
- Personal website or blog
- Theme showcase/directory
- Include a screenshot or preview
- Document any special features or design decisions
API Reference
loadThemeFromJson(json: string): void
Loads a theme from a JSON string. The function:- Parses the JSON
- Validates that
nameandcolorsfields exist - Applies all color tokens as CSS variables
- Persists the theme selection to localStorage
- Sets the
data-themeattribute on the document root
applyTheme(theme: Theme): void
Lower-level function that applies a theme object immediately. Usage:useTheme() Hook
Returns an object with:theme: Theme- Currently active themethemes: Theme[]- All built-in themessetTheme(theme: Theme): void- Switch to a themeloadThemeFromJson(json: string): void- Load custom theme