ztheme
A Zsh prompt for Git and runtime context, customizable themes, syntax highlighting, and autosuggestions.
Git state and language versions are resolved asynchronously. ztheme then displays the complete prompt in one update, avoiding partial or visually jumping prompt redraws.
Highlights
- Responsive prompt with asynchronous Git and runtime detection
- Git state powered by gitstatusd, without implicit fetches
- Themes for layout, colors, symbols, spacing, and input highlighting
- Automatic project detection for Rust, Python, Node.js, Go, Java, and more
- Sensible Zsh history, completion, navigation, and key-binding defaults
- No telemetry or network access during normal prompt use
Install
ztheme supports Zsh 5.9 or newer (including the zsh/system module, which
ships with Zsh) on macOS and Linux. A
Nerd Font is recommended for the default symbols.
cargo install ztheme --locked
ztheme setup
Add ztheme near the end of .zshrc:
Start a new shell:
exec zsh
ztheme setup installs the required Git helper and can also install
zsh-syntax-highlighting
and zsh-autosuggestions.
Use ztheme setup --yes for unattended setup.
Build from source with Rust 1.97 or newer:
git clone https://github.com/alexykn/ztheme.git
cd ztheme
cargo install --locked --path . --root ~/.local
ztheme setup
Ensure ~/.local/bin is on PATH.
Native archives for Apple Silicon, Intel macOS, x86_64 Linux, and arm64 Linux
are available on the Releases
page. Verify the archive against SHA256SUMS, place ztheme on PATH, and run
ztheme setup.
Themes
Explore available themes:
ztheme theme list
Catppuccin Mocha is selected by default. Vesper is bundled as an alternative:
ztheme theme apply vesper
Custom themes live in:
${XDG_CONFIG_HOME:-$HOME/.config}/ztheme/themes/
The active theme is selected in
${XDG_CONFIG_HOME:-$HOME/.config}/ztheme/config.toml:
= 1
= "my-theme"
Custom themes inherit every omitted value from Catppuccin Mocha. Save one as
themes/my-theme.toml; a useful theme can stay small:
= 1
[]
= "#89b4fa"
= "#7f849c"
= "#f9e2af"
= "#a6e3a1"
= "#f38ba8"
[]
= [
["directory", "git", "python", "rust"],
["character"],
]
= ["clock", "status"]
[]
= "on "
= " "
[]
= "❯"
= "❯"
= { = 1 }
Apply it, then use the edit-and-reload loop:
ztheme theme apply my-theme
ztheme theme edit my-theme
ztheme theme reload
Layouts may use directory, clock, git, character, status, and the runtime
segments python, perl, java, kotlin, scala, rust, go, bun,
deno, node, ruby, php, dotnet, c, cpp, swift, and lua.
Colors accept palette names or #RRGGBB. Styles support foreground,
background, bold, underline, and standout.
See the complete theme schema, including every layout and segment key.
Asynchronous rendering
Git and runtime segments are resolved asynchronously. Git is locked by
default: the prompt stays blank until Git resolves (or the shared deadline
expires), then appears in one atomic redraw. Runtime segments are unlocked
by default: the prompt renders as soon as Git is done and each runtime value is
drawn in when its version command finishes. That ordering reflects the real
cost of each group — gitstatusd is fast, while some runtime version commands
(such as swift) can take long enough to delay every prompt if the prompt
waited for them.
Configure this per group in config.toml:
= 1
= "my-theme"
[]
= true # wait for Git (default: true)
= false # don't wait for language/runtime versions (default: false)
git_segmentcontrols the Git segment. It defaults totrue(wait).runtime_segmentcontrols the language, package manager, and runtime segments (python,rust,node, and so on). It defaults tofalse(don't wait).
Setting a group to true makes the prompt wait for it (holding the whole
prompt blank until it resolves, then rendering once); false renders as soon
as every locked group is done and redraws that group in when it is ready. If
you unlock a group, be aware the prompt's width can change when that segment
later appears.
Syntax highlighting
Syntax highlighting is part of the theme, not a separate color configuration.
Run ztheme setup to install the managed
zsh-syntax-highlighting
integration.
Catppuccin Mocha already styles commands, arguments, paths, options, quotes, errors, and shell syntax. Override only what your theme needs:
[]
= { = "muted" }
= { = "accent" }
[]
= { = "success", = true }
= { = "success" }
= { = "success" }
= { = "path", = true }
= { = "text" }
= { = "text" }
= { = "accent" }
= { = "accent" }
= { = "muted" }
= { = "error", = true }
Every entry under input.syntax is optional and uses the same style fields as
prompt segments. Set a style to "none" to disable it explicitly:
[]
= "none"
Supported names follow zsh-syntax-highlighting's main, brackets, cursor, line,
and root highlighters. The built-in
themes/catppuccin-mocha.toml is the complete
reference and a good starting point for fine-grained overrides.
See syntax highlighting and input schema for the full list of accepted syntax-style names and configuration keys.
Shell defaults
ztheme provides a practical interactive baseline:
- persistent, deduplicated shared history
- cached, case-insensitive completion with hidden files
- prefix-aware Up and Down history search
- terminal-aware Home, End, Delete, word, and arrow-key bindings
- directory-stack navigation and interactive comments
- asynchronous autosuggestions with Right Arrow, End, or Ctrl-Space to accept
These are ordinary Zsh settings. Put overrides after initialization and your
.zshrc remains authoritative:
HISTSIZE=50000
To use only the prompt and input integrations:
ZTHEME_SHELL_DEFAULTS=0
Set ZTHEME_HISTORY_DEFAULTS=0 instead to disable only history defaults.
Set ZTHEME_KEY_BINDINGS=0 before initialization to disable ztheme's
navigation and autosuggestion bindings. Set ZTHEME_FOCUS_REPORTING=0 to
disable terminal focus tracking.
ztheme uses the active terminal's terminfo entry and supports both Emacs and Vi keymaps. On macOS, Option-based word movement and deletion require the terminal to send Option as Alt/Escape; this is usually named Esc+ in iTerm2 and Option as Alt in other terminals.
ztheme does not manage PATH, aliases, editor selection, terminal-emulator
preferences, or application environment variables.
Commands
| Command | Purpose |
|---|---|
ztheme setup |
Install or repair prompt helpers |
ztheme theme list |
Preview available themes |
ztheme theme apply NAME |
Apply and remember a theme |
ztheme theme edit NAME |
Open a theme in $VISUAL or $EDITOR |
ztheme theme reload |
Reload the current theme after editing |
ztheme clear |
Clear runtime values and reset Git status |
Updating and removal
Update a Cargo installation with:
cargo install ztheme --locked --force
To remove ztheme, delete the executable and its initialization line. Managed
data is stored below ${XDG_DATA_HOME:-$HOME/.local/share}/ztheme, cached data
below ${XDG_CACHE_HOME:-$HOME/.cache}/ztheme, and themes below
${XDG_CONFIG_HOME:-$HOME/.config}/ztheme.
Architecture
A per-shell client daemon renders prompts and talks to a per-user server
daemon that hosts runtime caching and the persistent gitstatusd client.
Keeping the client alive avoids spawning a process for every prompt.
See Architecture for subsystem ownership, protocols,
and the runtime-extension workflow. See Runtime cache for
cache identities, persistence, and limitations. See Segments
for the synchronous segment system, including user-defined segments. See
Benchmarks for measured prompt latency and cache behavior.
Built with
- Catppuccin provides the Mocha palette used by the default theme.
- Vesper provides the palette used by the bundled Vesper theme.
- gitstatusd provides fast Git status.
- zsh-syntax-highlighting highlights commands as they are typed.
- zsh-autosuggestions provides history-based suggestions.
License
MIT. gitstatusd is a separate GPL-3.0-licensed process.