Dynamic wallpaper color palette generator and theming engine.
(pronounced: spex)
Installation · Changelog · CLI · Extraction · Color Roles · spex-convert · Template Engine · Transforms
〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️〰️
Warning
Spex is still under active development and may behave inconsistently with some wallpapers. Palette generation can occasionally produce incorrect colors while the extraction and role-mapping logic is still being improved.
spex generates terminal palette previews so you can quickly inspect extracted colors before exporting or rendering templates.
- 🎨 High-quality palette extraction from wallpapers
- 🧠 LAB k-means extraction with mediancut fallback
- 🌈 Configurable palette tuning with
faithful,balanced, andvividpresets - 🌗 Dark and light theme modes
- 🧩 Config-driven template engine with loops and transformations
- ⚙️ Workflow automation with template hooks
- 🖥️ Terminal palette preview output
- 📦 Multiple export formats (
json,css,terminal) - 🔁 Companion
spex-convertCLI for migrating external templates - 🧱 Modular and extensible Rust architecture
Recommended installation method on Arch Linux.
Install with an AUR helper:
yay -S spex-binBuild from source via AUR:
yay -S spexDownload the v1.0.0 release tarball:
curl -L -o spex.tar.gz https://github.com/Grey-007/Spex/releases/download/v1.0.0/spex-linux-x86_64.tar.gzExtract it:
tar -xvf spex.tar.gzInstall the binaries into your PATH:
sudo install -Dm755 spex /usr/local/bin/spex
sudo install -Dm755 spex-convert /usr/local/bin/spex-convertcargo build --release
sudo install -Dm755 target/release/spex /usr/local/bin/spex
sudo install -Dm755 target/release/spex-convert /usr/local/bin/spex-convertBasic usage:
spex wallpaper.jpgCustom palette size:
spex wallpaper.jpg --colors 16Dark theme:
spex wallpaper.jpg --theme darkDry run:
spex wallpaper.jpg --dry-runForce mediancut:
spex wallpaper.jpg --extractor mediancutInspect extraction:
spex wallpaper.jpg --debug-extractor --debug-paletteVivid recovery mode:
spex wallpaper.jpg --vividspex-convert is the companion migration tool in this repo. It converts templates from other theming systems into Spex-compatible placeholders so existing configs are easier to move into a Spex workflow.
What it does:
- extracts tokens from template files
- detects common source styles such as pywal, Matugen, and CSS-like variables
- classifies semantic aliases with direct and fuzzy matching
- rewrites recognized tokens into Spex syntax
- reports unknown tokens while leaving unmatched content untouched
It understands token forms such as {token}, {{token}}, ${token}, $token, and nested Matugen braces like {{{{colors.primary.default.hex}}}}, which are normalized into canonical Spex tokens like {{colors.primary.hex}}.
Examples:
spex-convert theme.css
spex-convert theme.css --analyze
spex-convert theme.css --output converted.cssDefault behavior writes the converted template to converted_template.spex. --analyze prints detected tokens and suggested mappings without writing a file.
Templates are configured through config.toml and rendered with generated palette variables.
Directory layout:
~/.config/spex/
config.toml
templates/
Template variable examples:
{{background}}
{{primary}}
{{accent}}
{{colors.surface.hex}}
colors.* semantic role tokens are stable and map directly to generated theme roles:
colors.background->theme.backgroundcolors.surface->theme.surfacecolors.primary->theme.primarycolors.secondary->theme.secondarycolors.accent->theme.accentcolors.accent2->theme.accent2colors.highlight->theme.highlightcolors.text->theme.text
Role fallback is only used when a requested role is missing:
accent2->accentsurface->backgroundsecondary->primary
Theme background behavior:
- dark mode anchors the background near black and keeps only a restrained accent tint from the most expressive palette color
- light mode anchors the background near white and keeps a subtle accent tint from the same palette hint
surfacecomes from the next palette color closest in theme-relative luminance while still staying perceptually distinct from the background (Delta-E > 8)surface_containerandsurface_highare then stepped away fromsurfaceto keep layered backgrounds readable without inverting the theme orderprimary,secondary,accent, andaccent2are chosen from the most saturated palette colors that stay distinct from the background and from each othertextis chosen from the strongest-contrast endpoint so the final role order stays stable: background -> surface -> accents -> text
Low-saturation wallpaper handling:
- Spex can tune palette behavior with
preset,vibrancy_strength, andbackground_tint_strengthinconfig.toml --palette-preset vividor--vividpushes dull wallpapers harder toward brighter accents- the boost raises saturation and contrast while still following the wallpaper's dominant hue family
- grayscale palettes can receive a small hue hint from the wallpaper's dominant color region
For troubleshooting template role resolution, run with:
spex generate wallpaper.jpg --debug-theme--debug-theme now also prints the final semantic role assignments with:
- LAB values
- luminance
- saturation
- theme-relative depth
- contrast against background
- Delta-E distances between roles
For palette metrics and final role diagnostics, run with:
spex generate wallpaper.jpg --debug-colorsPreview only:
spex preview wallpaper.jpgGenerate shell completions:
spex completions fishDiagnostics:
spex doctorUse spex doctor to validate your environment before running full template workflows.
It checks:
- config file availability and parse validity
- template directories and template file readability
- template token validity (including
colors.*token paths) - hook command configuration (without executing hooks)
- Spex Color Engine token generation
- template rendering simulation with a mock palette
Example:
spex doctorDetailed docs are available in:
docs/extraction.mddocs/color_roles.mddocs/template_engine.mddocs/transformations.mddocs/hooks.mddocs/cli.mddocs/spex-convert.md
Issues and pull requests are welcome. If you have ideas for improvements, new template targets, or workflow enhancements, feel free to open a discussion.
Inspired by:
Licensed under the MIT License. See LICENSE.





