colorant
Per-directory terminal theme switcher with system dark/light mode support.
colorant walks up from your current directory looking for a .colorantrc
file and applies the theme it describes to your terminal. When you cd out
of the tree, the theme resets. When the OS flips between dark and light, the
active theme follows on the next shell prompt.
Status
Early development. Supported terminals: Ghostty and iTerm2 on macOS, driven from zsh. Other terminals (Kitty, WezTerm, Alacritty), shells, and OSes will land incrementally.
Install
Three install paths, all of which ship the same colorant binary built for
both Intel and Apple Silicon Macs.
Homebrew
The tap is auto-added on first install. Easiest path if you already use Homebrew.
Shell installer
|
No Rust toolchain or Homebrew required. Detects your architecture, downloads
the matching binary, and verifies its checksum. Installs to $CARGO_HOME/bin
(typically ~/.cargo/bin) — make sure that's on your $PATH. To install
elsewhere, set COLORANT_INSTALL_DIR=/some/path before running.
From source (cargo)
For Rust developers, or to pin a specific version:
# latest main
# pinned to a release tag
Installs to ~/.cargo/bin/colorant.
Verifying downloads
Each release publishes a .sha256 file alongside every archive, plus an
aggregated sha256.sum. If you download a tarball directly (rather than via
the shell installer, which verifies for you), check it with:
Quick start
# 1. Wire the zsh hook into your shell, then restart your shell.
# 2. Install the bundled palettes into your themes dir. (`colorant themes list`
# enumerates what's available; `--all` copies every bundled palette.)
# 3. Tag a directory with that palette.
# 4. cd back in (or just press Enter at the prompt) to see the theme apply.
The hook fires on every cd and on every prompt redraw, so themes update
both when you change directories and when macOS flips dark/light mode —
the latter applies on your next prompt (your next command or Enter press).
Commands
colorant --help is the canonical reference. The subcommands:
| Command | What it does |
|---|---|
colorant apply |
Walk up from the current directory to find the nearest .colorantrc, resolve it for the current dark/light mode, and emit OSC sequences to repaint the terminal. Silent no-op on unsupported terminals. If no rc is found, falls back to default_theme from ~/.config/colorant/config.toml (optional), otherwise emits a terminal reset. |
colorant reset |
Reset the terminal's foreground, background, cursor, and 16 palette entries to their defaults. |
colorant current |
Print the path of the .colorantrc that would be applied for the current directory. Empty output if none is found. |
colorant init <shell> |
Print a shell-specific integration snippet to stdout, intended for eval. Currently zsh only. |
colorant themes [<action>] |
Manage themes from bundled and remote sources (currently gogh). With no action, opens an interactive TUI that browses every source — installed + bundled + Gogh (when synced) — with a live preview that fetches Gogh palettes on demand. Keys: j/k=navigate, /=filter by name (Esc clears, Enter commits), s=cycle source filter (All → Bundled → Gogh), b=both, d=dark, l=light, c=clear picks, Enter=apply, q=quit. On apply, writes extends / extends.dark / extends.light to the cwd's .colorantrc, auto-installing any Gogh theme that wasn't on disk. With an action: list [--source X] [--installed] enumerates available themes; search <q> [--source X] filters by substring; sync [--source X] refreshes the remote catalog cache (network only happens here); apply <name> writes extends to the cwd's .colorantrc (or --dark <name> --light <name> for per-mode), auto-installing the palette from any source — qualify a remote theme as gogh:Dracula; install [<name>|--all] [--force] bulk-installs bundled palettes; path prints the themes dir. |
colorant doctor [path] |
Diagnose silent failures in a .colorantrc: unknown keys, invalid colors, malformed lines, unknown sections, and extends references whose palette files aren't on disk. Without path, walks up from the current directory like current. Exits 0 if nothing is wrong, 1 otherwise. |
colorant show [--all] |
Print the resolved colors that would apply for the current directory — each slot with its hex code and a 24-bit swatch. Defaults to the current OS mode; --all prints both dark and light. |
The apply command is what the shell hook calls on every chpwd /
precmd; you generally don't need to invoke it manually unless debugging.
Environment variables
COLORANT_MODE=dark|light— force a specific mode, bypassing macOS dark/light detection.
Config files
colorant reads up to three config files, all optional. See examples/
for annotated templates of the two main ones.
Palettes (.colorant) — flat color sets. No modes, no inheritance.
Live under ~/.config/colorant/themes/. Examples ship in this repo:
catppuccin-mocha.colorant, gruvbox-light.colorant, tokyo-night.colorant,
and a dozen more.
# tokyo-night.colorant
fg = #c0caf5
bg = #1a1b26
cursor = #c0caf5
tab_bg = #1a1b26 # iTerm2-only; ignored on Ghostty.
color0 = #15161e
# ...
Per-directory config (.colorantrc) — the file you author per
project. Picks parent palettes (globally or per-mode), and optionally
overrides specific keys.
# ~/work/myproject/.colorantrc
extends.dark = tokyo-night
extends.light = catppuccin-latte
# Project-wide override regardless of mode
fg = #ffffff
[dark]
# In dark mode only, recolor the cursor
cursor = #ff00ff
Global config (~/.config/colorant/config.toml) — applied when no
.colorantrc is found while walking up from the current directory.
Without it, colorant apply emits a terminal reset when no rc is found.
= "catppuccin-mocha"
# When true (default), if a theme doesn't set `tab_bg`, the iTerm2 tab
# color is derived from `bg` so the tab matches the terminal background.
# Set to false to leave the tab color alone unless a theme names it.
= true
Tab color and tmux
iTerm2 is the only currently-supported terminal that exposes a runtime
tab-color API (via OSC 1337 ; SetColors=tab=...). Inside tmux, that
sequence is dropped by default — add set -g allow-passthrough on to
~/.tmux.conf to let it through. The standard fg/bg/cursor/palette
sequences keep working either way (tmux handles them internally).
Ghostty has no equivalent runtime API today, so colorant doesn't emit
anything tab-related on Ghostty.
Uninstall
Match the method you used to install:
# Installed via Homebrew
# Installed via cargo install
# Installed via shell installer
Then remove the shell hook line from ~/.zshrc:
Optionally clear the config dir and any palettes you downloaded:
License
MIT. See LICENSE.