Use caelestia-dots on NixOS — without manual dotfile management.
caelestia-dots is a beautiful, feature-rich desktop environment built on Hyprland. But it's designed for traditional Linux distros: you clone the repo, run install scripts, and manually track updates. On NixOS this approach breaks — the system is immutable, paths are in /nix/store, and configs must be declared, not copied.
caelestianix solves this. It's a Home Manager module that:
- Reads upstream caelestia-dots configs at build time — Hyprland settings, keybinds, color schemes, animations, terminal configs, and more are parsed directly from the caelestia-dots repo during
nix build. No manual copying. - Automatically stays in sync — run
nix flake updateand all upstream changes flow in. No need to manually track what changed in caelestia-dots. - Adapts paths for NixOS — commands like
hyprpicker,cliphist,wpctlare automatically replaced with their/nix/store/...equivalents so everything actually works on NixOS. - Lets you override anything — thanks to infuse.nix, you can prepend, append, or replace any setting without forking upstream.
Note
Fork of caelestia-nix with upstream auto-sync, editor integrations (VSCode/Copilot), and expanded module coverage.
caelestia-dots repo (upstream) caelestianix (this module) Your NixOS system
┌─────────────────────────┐ ┌──────────────────────────────┐ ┌──────────────────────┐
│ hyprland/*.conf │──parse──▶ Nix attrsets │ │ │
│ variables.conf │──parse──▶ + substitute Nix store paths│──▶ │ ~/.config/hypr/... │
│ scheme/default.conf │──parse──▶ + user overrides (infuse) │ │ ~/.config/foot/... │
│ foot/foot.ini │──parse──▶ + Home Manager integration │ │ ~/.config/starship/ │
│ starship/starship.toml │──parse──▶ │ │ ... │
│ btop/btop.conf │──parse──▶ │ │ │
└─────────────────────────┘ └──────────────────────────────┘ └──────────────────────┘
17 config modules read from upstream automatically. Parsers handle each format:
- Hyprconf (
.conf) → customparseSections/parseVarsparser - TOML (starship) →
builtins.fromTOML - JSON (VSCode) →
builtins.fromJSON - INI (foot) → custom INI parser
- Key=Value (btop) → custom parser
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
caelestianix = {
url = "github:Xellor-Dev/caelestia-nixos";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { self, nixpkgs, home-manager, caelestianix }:
let
username = "youruser";
system = "x86_64-linux";
in {
homeConfigurations.${username} = home-manager.lib.homeManagerConfiguration {
pkgs = nixpkgs.legacyPackages.${system};
modules = [
caelestianix.homeManagerModules.default
./home.nix
];
};
};
}{ config, pkgs, ... }:
{
programs.caelestia-dots = {
enable = true;
# Enable the modules you want (caelestia is enabled by default)
hypr.enable = true; # Hyprland: all keybinds, colors, animations, etc from upstream
editor.enable = true; # VSCode/Zed/Micro from upstream
term.enable = true; # Fish + Starship + Eza from upstream
btop.enable = true; # System monitor from upstream
foot.enable = true; # Terminal emulator from upstream
};
# Rest of your Home Manager config (home.username, home.homeDirectory, etc)
}# Build your Home Manager configuration
home-manager switch
# That's it! Your system now has:
# - Hyprland with all upstream keybinds, animations, color scheme, variables
# - All Nix store paths automatically substituted (hyprpicker, wpctl, etc)
# - Terminal configured exactly like upstream (starship, fish aliases)
# - Editors (VSCode with GitHub Copilot if enabled)
# - System monitor (btop)# Pull latest caelestia-dots + nixpkgs updates
nix flake update
# Rebuild Home Manager
home-manager switch
# Done! All upstream changes are now applied to your systemWithout caelestianix (traditional approach — doesn't work on NixOS):
# Clone caelestia-dots
git clone https://github.com/caelestia-dots/caelestia ~/.config/caelestia
# Run install script
cd ~/.config/caelestia
./install.sh
# Manual steps to make paths work on NixOS (lots of breakage)
# Manually update when upstream changes
# No declarative config, hard to version controlWith caelestianix (NixOS-native approach):
# 1. Create flake.nix with caelestianix input (done once)
# 2. Create home.nix with programs.caelestia-dots config (done once)
# 3. Apply the configuration
home-manager switch
# 4. Get updates (whenever you want)
nix flake update
home-manager switch
# Everything is:
# - Declaratively defined in Nix
# - Version controlled (flake.lock locks all versions)
# - Reproducible (can recreate the same system on another machine)
# - Easy to customize (override anything with infuse.nix)-
Parse upstream configs → caelestianix reads from caelestia-dots flake input
hypr/hyprland/*.conf→ parsed into Nix attrsetshypr/variables.conf→ 58 variables extractedhypr/scheme/default.conf→ 106 color tokens loadedstarship/starship.toml→ TOML parsedvscode/settings.json→ JSON parsed- etc.
-
Substitute Nix store paths → commands replaced with real paths
hyprpicker → /nix/store/...-hyprpicker-0.4.5/bin/hyprpicker wpctl → /nix/store/...-wireplumber-0.4.X/bin/wpctl notify-send → /nix/store/...-libnotify-0.X/bin/notify-send -
Merge with your overrides → infuse.nix combines upstream with your settings
hypr.hyprland.keybinds.settings.bind.__append = [ "SUPER, Return, exec, footclient" # Your custom keybind ]; # Now you have all upstream keybinds PLUS your custom one
-
Generate Home Manager configuration → all files written to
~/.config/~/.config/hypr/hyprland.conf (generated from parsed upstream + your overrides) ~/.config/hypr/variables.conf ~/.config/hypr/hyprlandcolor.conf ~/.config/foot/foot.ini ~/.config/starship.toml ~/.config/Code/User/settings.json ... -
Activate → Home Manager manages the files
# home.nix
programs.caelestia-dots = {
enable = true;
hypr.enable = true;
# Add your keybind to upstream ones (don't override, just append)
hypr.hyprland.keybinds.settings.bind.__append = [
"SUPER, Return, exec, footclient" # Your custom bind
];
};home-manager switchResult: You now have all 95+ upstream keybinds from caelestia-dots PLUS your custom keybind.
No forking. No copy-paste. Just one line.
programs.caelestia-dots = {
enable = true;
hypr.enable = true;
# Override a specific color (keeps rest from upstream)
hypr.scheme.settings.colors.base00.__override = "#000000"; # Pure black instead
};home-manager switchResult: Color scheme is mostly from upstream with your one custom color.
| Module | What it configures | Upstream source |
|---|---|---|
hypr |
Hyprland WM — keybinds, animations, decorations, rules, input, gestures, env vars, color scheme, variables | hypr/hyprland/*.conf, hypr/variables.conf, hypr/scheme/default.conf |
editor.vscode |
VSCode/VSCodium + GitHub Copilot + product.json patching | vscode/settings.json |
editor.zed |
Zed editor settings | zed/settings.json |
editor.micro |
Micro terminal editor | micro/settings.json |
term |
Fish shell + Starship prompt + Eza aliases | starship/starship.toml |
btop |
System monitor | btop/btop.conf |
foot |
Foot terminal emulator | foot/foot.ini |
caelestia |
Caelestia shell integration & CLI tools | — |
Override any upstream setting without forking — infuse.nix merges your values with upstream:
programs.caelestia-dots = {
# Add your own keybinds alongside upstream ones
hypr.hyprland.keybinds.settings.bind.__append = [
"SUPER, Return, exec, footclient"
];
# Override a specific animation
hypr.hyprland.animations.settings.animations.animation.__override = [
"windows, 1, 3, easeOut, slide"
];
# Customize shell settings
caelestia.shell.settings = {
launcher.actionPrefix = ".";
battery.warnLevels.__prepend = [
{ level = 80; title = "High Battery"; message = "Unplug"; icon = "battery_5"; }
];
};
# VSCode extra settings
editor.vscode.settings.userSettings = {
"editor.fontSize" = 14;
"workbench.colorTheme" = "Tokyo Night";
};
};Available infuse.nix operations: __prepend, __append, __override, __delete
The hypr module optionally sets up supporting services:
programs.caelestia-dots.hypr.services = {
gnomeKeyring.enable = true; # Secret storage
polkitGnome.enable = true; # Privilege escalation
gammastep.enable = true; # Night light (geoclue2 or manual)
cliphist.enable = true; # Clipboard history
};All default to true but can be individually disabled.
- NixOS with Flakes enabled
- Home Manager
- x86_64-linux
- Wayland (for Hyprland module)
- caelestia-dots — the upstream dotfiles
- caelestia-nix — original module by Markus328
- infuse.nix — deep config merging
- Home Manager — declarative dotfiles on NixOS
Inherits the license from the original caelestia-nix project.