Skip to content

Theme format

Theme packages are JSON files that override chatwire's CSS variable system. They control colors, spacing, typography, avatar style, and can inject arbitrary CSS.

File location

Drop .json files in ~/.chatwire/themes/. They appear in Settings → Themes → Theme Packages automatically (no restart needed).

~/.chatwire/themes/
  my-dark-theme.json
  compact-mono.json

Top-level schema

{
  "name":       "my-theme",
  "author":     "Your Name",
  "version":    "1.0.0",
  "colors":     { ... },
  "structure":  { ... },
  "decorations":{ ... },
  "custom_css": "..."
}
Field Type Required Description
name string yes Lowercase kebab-case slug. Used as CSS selector and data-theme-pack attribute.
author string no Display name shown in the UI
version string no Semver string, shown in the UI
colors object no CSS color variable overrides
structure object no Spacing, radius, font overrides
decorations object no Avatar, bubble, shadow overrides
custom_css string no Arbitrary CSS injected into the document

Any combination of sections is valid — a colors-only package, a structure-only package, or all four together.

colors section

Maps semantic token names to CSS color values. Any valid CSS color syntax works: hex, rgb(), hsl(), oklch(), named colors.

Color tokens

Token Used for
background App background
foreground Default text color
card Card / panel background
card-foreground Text on cards
popover Dropdown / popover background
popover-foreground Text in popovers
primary Primary action color (buttons, highlights)
primary-foreground Text on primary-colored elements
secondary Secondary UI elements
secondary-foreground Text on secondary elements
muted Muted background (subtle panels)
muted-foreground Muted / de-emphasized text
accent Accent highlights
accent-foreground Text on accent elements
destructive Destructive action color (delete, error)
destructive-foreground Text on destructive elements
border Border color
input Input field background
ring Focus ring color
sidebar-bg Sidebar background (can differ from background)
info Info state color
warning Warning state color
success Success state color
msg-me Sent message bubble background
msg-me-text Sent message text color
msg-them Received message bubble background
msg-them-text Received message text color
msg-sms SMS/RCS message bubble background
msg-sms-text SMS/RCS message text color

Example

"colors": {
  "background": "#0d1117",
  "foreground": "#c9d1d9",
  "primary": "#58a6ff",
  "sidebar-bg": "#010409",
  "msg-me": "#1f6feb",
  "msg-me-text": "#ffffff",
  "msg-them": "#21262d",
  "msg-them-text": "#c9d1d9",
  "border": "#30363d"
}

structure section

Controls spacing, sizing, and typography. Values must be valid CSS length strings (0.5rem, 8px, 1).

Token Used for
radius Base border-radius
radius-bubble Message bubble corner radius
radius-input Input field corner radius
spacing-message Vertical gap between messages
spacing-sidebar Vertical gap between sidebar items
font-size-message Message text font size
font-size-sidebar Sidebar text font size
shadow-card Box shadow for cards
sidebar-width Sidebar panel width

Example

"structure": {
  "radius-bubble": "4px",
  "radius-input": "4px",
  "spacing-message": "2px",
  "font-size-message": "0.9rem",
  "sidebar-width": "260px"
}

decorations section

Fine-grained visual details: avatars, bubble styles, borders, and animations.

Token Used for
avatar-shape Avatar border-radius (50% = circle, 0 = square, 8px = rounded)
avatar-size Avatar width/height
avatar-border CSS border for avatars
bubble-shadow Box shadow on message bubbles
bubble-tail Custom CSS for the message tail decoration
header-shadow Box shadow on the chat header bar
header-border Border on the chat header bar
sidebar-divider Divider between sidebar items
border-width Global border width
transition-speed Animation/transition duration

Example

"decorations": {
  "avatar-shape": "8px",
  "bubble-shadow": "0 2px 6px rgba(0,0,0,0.25)",
  "header-border": "none",
  "transition-speed": "100ms"
}

custom_css section

Arbitrary CSS injected verbatim into a <style> block in the document.

"custom_css": ".message-timestamp { font-style: italic; opacity: 0.7; }"

Security restrictions

Before injection, chatwire sanitizes custom_css:

  • @import rules are stripped — external stylesheets cannot be loaded
  • url(http://...) and url(https://...) are replaced with url(about:blank) — prevents tracking pixels and external requests

Everything else is preserved: selectors, animations, custom properties, var(), calc(), pseudo-elements. data: URIs and fragment references (url(#id)) are always preserved.

When sanitization occurs, the UI shows a notice: "This theme includes custom CSS (some external references were sanitized)."

How activation works

  1. Drop your .json file into ~/.chatwire/themes/
  2. Open Settings → Themes → Theme Packages
  3. Select the package from the dropdown
  4. The package CSS is injected and data-theme-pack="<name>" is set on <html>
  5. All variable overrides become active immediately

Priority order

Later layers override earlier ones:

  1. Base CSS (chatwire defaults)
  2. Built-in scheme variables
  3. Theme package variables
  4. Individual accent color override (Settings → Accent color)
  5. Custom CSS (Settings → Custom CSS)

Your per-Settings overrides always win over the theme package. Import a package for its overall aesthetic and override specific colors in Settings without editing the file.

Example: complete GitHub Dark package

{
  "name": "github-dark",
  "author": "chatwire community",
  "version": "1.0.0",
  "colors": {
    "background": "#0d1117",
    "foreground": "#e6edf3",
    "card": "#161b22",
    "card-foreground": "#e6edf3",
    "primary": "#58a6ff",
    "primary-foreground": "#ffffff",
    "secondary": "#21262d",
    "secondary-foreground": "#c9d1d9",
    "muted": "#161b22",
    "muted-foreground": "#8b949e",
    "accent": "#1f6feb",
    "accent-foreground": "#ffffff",
    "destructive": "#f85149",
    "destructive-foreground": "#ffffff",
    "border": "#30363d",
    "input": "#21262d",
    "ring": "#58a6ff",
    "sidebar-bg": "#010409",
    "msg-me": "#1f6feb",
    "msg-me-text": "#ffffff",
    "msg-them": "#21262d",
    "msg-them-text": "#c9d1d9"
  },
  "structure": {
    "radius-bubble": "6px",
    "radius": "6px"
  },
  "decorations": {
    "avatar-shape": "50%"
  }
}

Sharing themes

Theme packages are self-contained JSON files. Share them directly — recipients drop the file in ~/.chatwire/themes/ and it appears in the picker immediately.