The Reactive Theme Engine for Hyprland
Compile your rice into a high-performance, event-driven daemon
Features β’ Quick Start β’ Documentation β’ Examples β’ Contributing
hypricer is not just another dotfile manager. It's a theme transpiler that compiles declarative theme definitions into optimized Rust binaries that run as system daemons.
Traditional Linux theming approaches suffer from:
- π Shell script overhead - Every theme change spawns new processes
- π₯ Runtime failures - Missing dependencies crash your desktop
- π Manual updates - You have to trigger theme changes yourself
- π No validation - Broken configs only fail at runtime
- β‘ Zero-latency reactions - Native code execution, no shell overhead
- π‘οΈ Build-time validation - Dependencies checked before compilation
- π¨ Truly reactive themes - Your desktop adapts to system state automatically
- π§ Type-safe logic - Theme logic is Rust code that must compile
Example: Window borders automatically change color based on CPU load, time of day, or active application - with zero latency and complete type safety.
- π Instant Updates - Changes apply in <1ms, compiled to native code
- π Reactive Themes - Desktop adapts to music, battery, time, CPU, and more
- π‘οΈ Dependency Safety - Build fails if required tools aren't installed
- π¦ Modular Design - Mix and match components from different themes
- π Transparent - Inspect generated Rust code for debugging
- π¦ Rust-Powered Logic - Write theme logic in a real programming language
- π Rich Registry System - Extensible catalog of watchers, providers, and components
- π Hot Reload - Rebuild and restart daemon with one command
- π¨ Template System - Familiar
{{ variable }}syntax in configs - π§ͺ Type Safety - Invalid theme logic won't compile
- Hyprland (obviously!)
- Rust & Cargo (1.70+)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
- Common tools (optional, theme-dependent):
jq- JSON parsinghyprctl- Hyprland control (comes with Hyprland)
-
Clone the repository
git clone https://github.com/yourusername/hypricer ~/.config/hypr/hypricer cd ~/.config/hypr/hypricer
-
Build the CLI tool
cargo build --release
-
Add to your Hyprland config
Edit
~/.config/hypr/hyprland.confand add at the top:source = ~/.config/hypr/hypricer/live/active_session.conf -
Build and apply a theme
./target/release/hypricer build --profile seiki
# Check if the daemon is running
ps aux | grep hrm_daemon
# View live logs
tail -f ~/.config/hypr/hypricer/live/daemon.log
# Reload Hyprland to see changes
hyprctl reload- Installation Guide - Detailed setup instructions
- User Manual - Using hypricer day-to-day
- Troubleshooting - Common issues and solutions
- Theme Developer Guide - Creating custom themes
- Registry Manual - Extending the component catalog
- Architecture Overview - How hypricer works internally
- API Reference - Complete API documentation
- Seiki Theme - Advanced reactive theme showcase
- Modern Dark - Simple starter theme
Theme logic (themes/myrice/logic/style.rs):
use crate::Context;
pub fn resolve(ctx: &Context) -> String {
let cpu = ctx.data.get("cpu_usage")
.and_then(|s| s.parse::<i32>().ok())
.unwrap_or(0);
let color = match cpu {
0..=30 => "rgba(33ccffee)", // Blue: Peace Mode
31..=70 => "rgba(ffaa00ee)", // Orange: Active
_ => "rgba(ff4444ee)", // Red: Mecha Mode!
};
format!("general {{ col.active_border = {} }}", color)
}Registry definition (catalog/registry/time.toml):
[watcher.time_part]
provider = "poll_cmd"
interval = 60000 # Check every minute
cmd = """
hour=$(date +%H);
if [ "$hour" -ge 6 ] && [ "$hour" -lt 9 ]; then echo "Dawn";
elif [ "$hour" -ge 9 ] && [ "$hour" -lt 17 ]; then echo "Day";
elif [ "$hour" -ge 17 ] && [ "$hour" -lt 20 ]; then echo "Sunset";
else echo "Night"; fi
"""Theme logic:
pub fn resolve(ctx: &Context) -> String {
match ctx.data.get("time_part").map(|s| s.as_str()) {
Some("Dawn") => "exec = swww img ~/wallpapers/dawn.png",
Some("Day") => "exec = swww img ~/wallpapers/day.png",
Some("Sunset") => "exec = swww img ~/wallpapers/sunset.png",
_ => "exec = swww img ~/wallpapers/night.png",
}.to_string()
}βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Build Time β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β 1. hypricer CLI β
β β β
β ββ Load Registry (catalog/registry/*.toml) β
β β β’ Watchers (system event listeners) β
β β β’ Providers (on-demand data fetchers) β
β β β’ Static components (config files) β
β β β
β ββ Load Theme (themes/*/theme.toml) β
β β β’ Metadata β
β β β’ Static component selections β
β β β’ Dynamic logic references β
β β β
β ββ Validate Dependencies β
β β β’ Run all 'check' commands β
β β β’ Fail fast if tools missing β
β β β
β ββ Generate Daemon Source β
β β’ Copy logic/*.rs β generated/src/logic/ β
β β’ Generate main.rs with watchers, providers β
β β’ Inject template.conf content β
β β
β 2. Cargo Build β
β β β
β ββ Compile generated source β Binary daemon β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Runtime β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β Daemon (generated/target/release/hrm_daemon) β
β β β
β ββ Watchers (background threads) β
β β ββ Push events to coordinator: Event(key, value) β
β β β
β ββ Coordinator (main loop) β
β β ββ Receives events from watchers β
β β ββ Debounces (50ms) to avoid thrashing β
β β ββ Fetches all providers (parallel, 200ms timeout) β
β β ββ Calls theme logic functions β
β β ββ Updates live/active_session.conf β
β β β
β ββ Hyprland β
β ββ Automatically reloads when config changes β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Key Design Principles:
- Separation of Concerns: Build-time (validation) vs Runtime (execution)
- Fail Fast: Dependency issues caught during build, not at 3am
- Performance: Native code, zero shell overhead
- Transparency: Generated code is human-readable Rust
A showcase of hypricer's capabilities featuring:
- β¨ Three distinct modes (Peace, Mecha, Focus)
- π Day/night cycle with automatic wallpaper switching
- π΅ Music-reactive styling
- β‘ CPU load-based border colors
A simple, elegant starter theme perfect for learning:
- π¨ Clean, minimal aesthetics
- π± Good defaults for modern workflows
- π§ Easy to customize
View Modern Dark Documentation β
We welcome contributions! Here's how you can help:
- π Bug reports: Use the issue template, include logs
- π‘ Feature requests: Describe the use case clearly
- π Documentation: Typos, clarity improvements
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Test thoroughly (see CONTRIBUTING.md)
- Submit a pull request
Themes are especially welcome! See the Theme Developer Guide.
Add new watchers, providers, or components to catalog/registry/. See the Registry Manual.
-
stream_cmdprovider (forplayerctl --followstyle commands) - File system watchers (
inotifyintegration) - DBus signal watchers
- Web UI for theme management
- Theme marketplace/gallery
- Multi-monitor support with per-monitor themes
- Theme inheritance system
- Live theme preview mode
- Performance profiling tools
This project is licensed under the MIT License - see the LICENSE file for details.
- Hyprland - The amazing Wayland compositor this is built for
- The Rust Community - For incredible tooling and libraries
- Unixporn Community - Inspiration and feedback
- Discord: Join our server (coming soon)
- Reddit: r/hypricer (coming soon)
- Matrix:
#hypricer:matrix.org(coming soon)
Made with β€οΈ and Rust for the Hyprland Community
If you find this project useful, consider giving it a β on GitHub!
Report Bug β’ Request Feature β’ Discussions