A brutally fast, zero-compromise Wayland status bar for Hyprland.
Built in Rust. Styled with intention. Designed to disappear.
Most status bars try to be everything. Zenith tries to be invisible — a 28-pixel strip of exactly the information you need, rendered at the speed of a compiled binary, consuming single-digit megabytes of RAM.
- Native Wayland — No X11 compatibility layers. Pure
wlr-layer-shellvia GTK4. - Compiled, not interpreted — Rust with LTO, stripped symbols, single codegen-unit. Startup in under 50ms.
- Zero-blocking I/O — External processes (playerctl) run on background threads. The main GTK loop never stalls.
- Opinionated aesthetics — Tokyo Night Storm palette, Inter + JetBrainsMono Nerd Font typography, hand-tuned spacing. Beautiful by default, fully customizable via CSS.
| Module | Description |
|---|---|
| Clock | Configurable strftime format with per-second updates |
| Calendar | Clickable date badge → full GTK4 calendar popover |
| System Stats | Real-time CPU %, memory %, and CPU temperature with color-coded thermal states |
| Media Player | playerctl-powered now-playing with artist/title, play/pause toggle, and a 60fps smoothly-interpolated progress bar |
| Todo List | Full CRUD task manager with priority levels (P1–P9), persistent JSON storage, and an inline progress bar |
Additional highlights:
- 🎨 Fully themeable — Every element is a CSS class. Ship your own
style.css. - ⚙️ Deep merge config — Only override what you change. Missing keys fall back to sane defaults.
- 🖥️ Multi-monitor — Target a specific output by connector name (
DP-1,HDMI-A-1, etc.). - 🔲 Floating or flush — Switch between a flush edge-to-edge bar and a floating pill with animated RGB borders — just change two config values.
- 🧱 Atomic persistence — Todo data is written via temp-file + rename. No corruption on crash.
The recommended installation method for Arch users:
# Using paru
paru -S zenith-bar
# Using yay
yay -S zenith-barDependencies: gtk4, gtk4-layer-shell, rust (1.70+)
# Clone the repository
git clone https://github.com/CPT-Dawn/Zenith.git
cd Zenith
# Build the optimized release binary
cargo build --release
# Install to your PATH
sudo install -Dm755 target/release/zenith /usr/local/bin/zenith
# (Optional) Install default config and style templates
install -Dm644 Default_Config.toml ~/.config/zenith/config.toml
install -Dm644 Default_Style.css ~/.config/zenith/style.cssTip
If you skip the optional config step, Zenith will automatically create ~/.config/zenith/config.toml and style.css with sensible defaults on first launch.
Zenith reads its configuration from:
~/.config/zenith/config.toml # Behavior, geometry, module toggles
~/.config/zenith/style.css # Full CSS stylesheet
~/.config/zenith/todos.json # Todo persistence (auto-managed)
Override the config path at runtime with ZENITH_CONFIG=/path/to/config.toml.
[bar]
# Monitor connector (leave commented for default)
# monitor = "DP-1"
height = 28 # Bar height in pixels
gap_horizontal = 0 # Side margins (0 = flush)
gap_top = 0 # Top margin (0 = flush)
border_radius = 0 # Corner radius (0 = sharp)
border_width = 0 # Animated border thickness (0 = hidden)
rgb_cycle_seconds = 12.0 # Border animation cycle duration
background = "rgba(26, 27, 38, 0.95)"
[modules]
clock = true
clock_format = "%a %H:%M" # strftime syntax
system_stats = true
playerctl = true
todo = trueTo transform Zenith from a flush top bar into a floating pill with an animated RGB border:
[bar]
height = 36
gap_horizontal = 12
gap_top = 8
border_radius = 14
border_width = 2The stylesheet at ~/.config/zenith/style.css uses standard GTK4 CSS. Every widget has a semantic class name (e.g. .zenith-module-surface, .zenith-player-title, .zenith-todo-row).
Key classes for customization:
| Class | What it controls |
|---|---|
.zenith-inner |
Main bar background surface |
.zenith-module |
Base typography for all modules |
.zenith-module-surface |
Hover/active background for interactive elements |
.zenith-module-left |
Left cluster accent color (Todo) |
.zenith-module-center |
Center cluster accent color (Clock/Calendar) |
.zenith-module-right |
Right cluster accent color (System/Player) |
.zenith-module-temp-cool |
Temperature < 50°C |
.zenith-module-temp-warm |
Temperature 50–75°C |
.zenith-module-temp-hot |
Temperature > 75°C |
Font requirements: Inter and JetBrainsMono Nerd Font are expected. Zenith degrades gracefully to system sans-serif/monospace if they are not installed.
Add a few lines to your ~/.config/hypr/hyprland.conf for the best experience:
exec-once = zenith# --- Zenith Status Bar ---
layerrule = blur on, match:namespace zenith
layerrule = ignore_alpha 0.3, match:namespace zenithThe ignorealpha 0.3 threshold ensures only the bar surface is blurred — fully transparent regions (e.g., gaps in floating mode) are left untouched.
| Variable | Purpose |
|---|---|
ZENITH_CONFIG |
Override config file path |
ZENITH_STYLE |
Override style file path |
GSK_RENDERER |
Override GTK renderer selection (ngl, vulkan, gl, cairo, etc.) |
RUST_LOG |
Control log verbosity (info, debug, trace) |
If GSK_RENDERER is unset, Zenith defaults it to gl at startup for better
stability on mixed Wayland/Vulkan setups.
main.rs → env_logger → config::load() → GTK Application → ui::build_bar()
config.rs → TOML parsing and first-run scaffolding
style.rs → CSS template rendering, token substitution, backward-compat injection
ui.rs → wlr-layer-shell window, CenterBox widget tree, monitor targeting
modules/
clock.rs → 1s chrono timer
calendar.rs → Date button + Calendar popover (60s refresh)
system.rs → sysinfo CPU/mem + sysfs thermal (2s polling)
playerctl.rs → Background-thread subprocess polling + 60fps progress lerp
todo.rs → CRUD + priority + atomic JSON persistence
Contributions are welcome. Before submitting a PR:
- Run
cargo clippy -- -D warningsand ensure zero warnings. - Run
cargo fmt --checkto verify formatting. - Test on a live Wayland session (Hyprland preferred).
MIT © Swastik Patel