Themis is a theme orchestrator CLI for Linux and macOS. It switches your whole desktop between themes (Light/Dark and beyond) by coordinating profiles, palettes, and per-application integrations from a single command.
Themis acts as a "General Contractor" for theming—it doesn't generate colors, it manages the who, what, and when of applying them. You bring the palettes and templates; Themis renders them, links them, and reloads the right apps, atomically and without clobbering your hand-written config.
themis load dark # one command re-themes every enrolled app- Profile-based theming: Define profiles that include color palettes and app-specific settings
- Palette inheritance: System palettes (nord, dracula, etc.) can be extended by user palettes
- Multiple integration types: Templates, symlinks, commands, and scripts
- Safety-first: Generates hidden partials (
.themis.conf) that users manually include - Dry-run mode: Preview changes without modifying files
- Cross-platform: Runs on Linux and macOS, honoring
XDG_CONFIG_HOME/XDG_STATE_HOMEon both
Download the prebuilt themis binary and put it on your PATH:
curl -fsSL https://raw.githubusercontent.com/TwoWells/Themis/main/install.sh | shThe installer detects your OS/arch, verifies the release checksum, and installs to ~/.local/bin
(override with THEMIS_INSTALL_DIR). Ensure that directory is on your PATH.
If you have a Rust toolchain, the crate is published as themis-cli (the binary stays themis):
# No-compile: fetches the prebuilt release binary
cargo binstall themis-cli
# From source
cargo install themis-cliBuild from source with themis, or grab the prebuilt
binary with themis-bin:
# build from source
yay -S themis
# prebuilt binary
yay -S themis-binThe quick installer and cargo paths above both work on macOS. A Homebrew tap is on the way:
# coming soon
brew install twowells/tap/themisNote: Themis themes whatever has config files. Its example enrollments (waybar, hyprland, …) are Linux desktop apps; on macOS you point it at the configs you actually run.
Requires Rust (see rust-toolchain.toml for the pinned
version).
git clone https://github.com/TwoWells/Themis.git
cd Themis
# User install (no sudo, installs to ~/.local)
make install PREFIX=~/.local
# System install (requires sudo, installs to /usr/local)
sudo make installThis installs the binary and shell completions for bash, zsh, and fish. For a user install, ensure
~/.local/bin is on your PATH.
To uninstall:
# User uninstall
make uninstall PREFIX=~/.local
# System uninstall
sudo make uninstall# Initialize configuration
themis init
# Load a profile
themis load my-profile
# Check current status
themis status
# Verify configuration
themis verify
# Check app configurations
themis doctorThemis resolves every path from the
XDG Base Directory variables on Linux
and macOS alike, with $HOME-relative fallbacks — no platform-native locations, so a config tree
ports between machines unchanged:
- Config —
$XDG_CONFIG_HOME/themis/(default~/.config/themis/): holdsthemis.yaml,profiles/<name>.yaml, yourpalettes/<name>.yaml, andtemplates/<app>.j2 - State —
$XDG_STATE_HOME/themis/state.json(default~/.local/state/themis/state.json) - System palettes — each entry of
$XDG_DATA_DIRS(default/usr/local/share:/usr/share), searched as<dir>/themis/palettes/<name>.yaml; on macOS the Homebrew prefixes (/opt/homebrew/share,/usr/local/share) are searched too
See the documentation for the full resolution rules.
The main configuration file enrolls applications:
enroll:
kitty:
type: template
input: "~/.config/themis/templates/kitty.j2"
output: "~/.config/kitty/.themis.conf"
reload_signal: SIGUSR1
waybar:
type: template
input: "~/.config/themis/templates/waybar.j2"
output: "~/.config/waybar/colors.css"
reload_cmd: "pkill -SIGUSR2 waybar"
gtk:
type: command
commands:
- "gsettings set org.gnome.desktop.interface color-scheme '{{ color_scheme }}'"Profiles define variables and can include palettes:
# profiles/my-dark.yaml
include: nord # Include the nord palette
vars:
color_scheme: prefer-dark
transparency: 0.95Palettes define color variables:
# palettes/nord.yaml (or system: /usr/share/themis/palettes/nord.yaml)
vars:
bg: "#2e3440"
fg: "#eceff4"
accent: "#88c0d0"Palettes can inherit from other palettes using include.
Renders Jinja2 templates with profile variables:
kitty:
type: template
input: "~/.config/themis/templates/kitty.j2"
output: "~/.config/kitty/.themis.conf"
reload_cmd: "kill -SIGUSR1 $(pgrep kitty)" # optional
reload_signal: SIGUSR1 # optional (uses pkill)Creates symlinks with variable interpolation in the source path:
alacritty:
type: symlink
source: "~/.config/themis/configs/alacritty-{{ mode }}.toml"
target: "~/.config/alacritty/colors.toml"Executes shell commands with variable interpolation:
gtk:
type: command
commands:
- "gsettings set org.gnome.desktop.interface gtk-theme '{{ gtk_theme }}'"
- "gsettings set org.gnome.desktop.interface color-scheme '{{ color_scheme }}'"Executes external scripts with environment variables:
custom:
type: script
path: "~/.config/themis/scripts/custom.sh"
args: ["--mode", "{{ mode }}"]
env:
CUSTOM_VAR: "value"All profile variables are passed as THEMIS_<VAR> environment variables.
| Command | Description |
|---|---|
load <PROFILE> |
Load a profile and apply to all enrolled apps |
load <PROFILE> --dry-run |
Preview changes without writing files |
status |
Show currently loaded profile |
init |
Create initial configuration structure |
verify |
Validate configuration and profiles |
doctor |
Check app configurations for proper include patterns |
completions <SHELL> |
Generate shell completions (bash, zsh, fish) |
If you used sudo make install, completions are already installed system-wide.
For manual setup (or if you used PREFIX=~/.local):
# Bash (add to ~/.bashrc)
eval "$(themis completions bash)"
# Zsh (add to ~/.zshrc)
eval "$(themis completions zsh)"
# Fish (add to ~/.config/fish/config.fish)
themis completions fish | sourceAfter enrolling an app, you need to include the generated config in your app's main configuration.
Run themis doctor to see what changes are needed.
Example for kitty (~/.config/kitty/kitty.conf):
include .themis.conf
Full docs—getting started, profile and integration guides, and the CLI/configuration reference—live at twowells.github.io/Themis.
AGPL-3.0-or-later. See LICENSE for details.