Caelestia Shell (Quickshell) + Hyprland, on Ubuntu 24.04 / Zorin OS 18 / Mint 22 / Pop!_OS 22.04 — one script, zero manual config.
Caelestia officially supports Arch-based distributions only. This repository backports the full experience to Ubuntu-family systems: it builds Quickshell and the Caelestia shell from source against a pinned Qt 6.11.2 (the same Qt version Arch currently ships, which is what Caelestia upstream develops against), installs every dependency, and deploys the maintainer's exact desktop — theme, panels, animations, wallpapers, fonts, idle/lock behaviour — as a side-by-side session. GNOME stays completely untouched.
git clone https://github.com/12errh/caelestia-ubuntu.git
cd caelestia-ubuntu
sudo apt install -y shellcheck # optional, for the lint step
./setup.sh # interactive; --yes for unattendedReboot, pick Hyprland in the GDM gear menu, and log in.
You don't have to use the terminal at all — the repository ships a complete desktop app (GTK4/libadwaita, no extra Python packages) that wraps every script:
- Install wizard — system checks, install options, sudo password (kept in memory only), live progress log and result. Re-running is a safe repair.
- Setup screen — paginated wallpaper previews loaded in the background, appearance controls (transparency, rounding, animation speed, font scale), and idle/lock timers.
- Keybindings screen — every Hyprland shortcut from
hyprland.confand the files it sources, grouped by section. Add one by pressing the keys (grabbed automatically, checked against the existing bindings first), then choose what it does: launch an installed app from a searchable list, run a command, or a ready-made desktop action. Edits are validated, written atomically and backed up, with a one-click undo. - Updates screen — published maintainer-tested revision checks and desktop updates to accepted pins with a live log. The installed version and app updates live in the About screen; installation is manual.
- Advanced tab — install overrides, shell editor/restart, experimental upstream builds, Keep/Revert, runtime repair, and confirmed uninstall. Cancelling an upstream build restores pre-build pins, not installed binaries. Revert restores saved pins and rebuilds; it is not a full system rollback.
- Built-in guides — first login, every keybind, wallpaper & dynamic colours, idle/lock behaviour, updating and troubleshooting.
./app/run.py # run straight from a clone
sudo ./app/install.sh # or install into the app grid
./app/run.py --check # headless system report (no GUI)The easiest way to install the app on Ubuntu / Zorin / Mint / Pop is to
download the .deb from the
latest GitHub Release:
sudo apt install ./caelestia-installer_*_all.debThe package installs the app only (the Caelestia desktop itself is still built from within the app). See docs/INSTALL_APP.md for details and manual build options (maintainers).
Use one install method.
/usr/localand~/.localare searched before/usr, so addingsudo ./app/install.shon top of the package makes the older app and its older icon win. Since v1.2.1 the package removes such a leftover automatically andapp/install.shrefuses to create one — see Don't mix install methods.
See app/README.md and the complete user guide (also built into the app).
This is what you get on the first login — no tweaking required.
![]() |
![]() |
| Desktop — wallpaper, bar, audio visualiser | Dashboard — quick toggles, system info |
![]() |
![]() |
Launcher — apps, > actions, >wallpaper picker |
Session — logout / reboot / shutdown |
The whole interface (bars, drawers, lock screen, OSD) recolours itself from the
wallpaper. Switch it with >wallpaper in the launcher or
caelestia wallpaper -f <file>.
The same configuration running on the maintainer's machine:
| Area | Details |
|---|---|
| Theme | Rubik / CaskaydiaCove NF / Material Symbols Rounded, 0.55 base / 0.42 layer transparency, 1.35 rounding |
| Background | animated wallpaper layer with a blurred desktop clock (bottom-right, 1.15×) + 51-bar audio visualiser (blurred, auto-hide) |
| Bar | logo → workspaces → active window → tray → clock → status → power, hover-reveal, scroll actions |
| Animations | global duration scale 1.4, smooth bezier window motion |
| Idle / lock | 3 min lock → 5 min dpms off → 10 min suspend-then-hibernate, audio-aware inhibition, fingerprint unlock via quickshell PAM |
| Resume | shell auto-bounce + automatic lock re-acquisition after lid open (systemd-sleep hooks included) |
| Keybinds | SUPER-centred workflow incl. resize submap, hyprshot, wlogout, launcher/drawer IPC |
- Qt 6.11.2 toolchain under
/opt(viaaqtinstall, includesqtimageformats/webp +qtshadertools). On re-runs an existing Qt that the deployedqsalready links is reused — no re-download. - wayland 1.26 →
/usr/local(Qt 6.11's Wayland private headers need thewl_fixestype, absent from Ubuntu 24.04's wayland 1.22; the newer wayland is ABI-compatible, so GNOME and system packages are unaffected). - Hyprland +
hyprlock/hypridle/hyprpaper+ portals (PPAppa:cppiber/hyprland). - Quickshell (git master) built with vendored
cpptrace, RPATH-baked so no globalLD_LIBRARY_PATHis ever needed. - Caelestia shell (git master) — QML tree in
~/.config/quickshell/caelestia, plugin in/lib/qt6/qml/Caelestia. - m3shapes (Material 3 shapes) + libcava (audio visualiser backend).
- caelestia CLI (via
uv/pipx), all fonts, and Chrome + Bazaar flatpaks (best-effort, non-fatal).
- Ubuntu 24.04 or a derivative (Zorin 18, Mint 22, Pop!_OS 22.04), x86_64.
- ~8 GB free on
/(Qt toolchain ≈ 1.5 GB, build caches ≈ 2 GB). CI runners redirect the heavy writes onto a large workspace disk — on a normal machine you can pass--ignore-spaceif/is tight and a bigger disk is mounted. - Working internet connection,
sudoaccess. - A GPU with Mesa graphics drivers (Intel iGPU Haswell and newer, AMD, or
NVIDIA with
mesa/nouveau; proprietary NVIDIA works but is untested here).
./setup.sh # interactive
./setup.sh --yes # unattended install| Flag | Effect |
|---|---|
--yes |
no confirmation prompts |
--skip-apt |
skip the package stage (re-runs) |
--skip-qt |
Qt already installed |
--skip-fonts |
skip font downloads |
--skip-config |
build only; do not touch ~/.config |
--qt-version X |
use a different Qt (must be ≥ 6.11) |
--ignore-space |
skip the 8 GB free-disk check |
The installer is idempotent — re-running it updates sources and rebuilds
only what moved, and reuses an already-installed Qt toolchain. Existing user
configs are backed up to ~/.config/caelestia-ubuntu-backup-<timestamp> before
anything is overwritten.
CI note: the GitHub Actions workflow runs
setup.sh --yes --skip-fontson a fresh Ubuntu 24.04 runner and then asserts on the build's outputs (built binaries, templated configs, deployed Qt modules) inscripts/ci-verify-install.sh. Hyprland itself is not launched there — aquamarine (its backend) needs a DRM render node for a GBM allocator, which GPU-less CI runners don't expose.
./update.sh # check + apply (prompts before rebuild)
./update.sh --yes # apply non-interactively
./update.sh --check # read-only: report drift without cloning or buildingupdate.sh reads the manifest written by setup.sh. Every built component is
compiled from an exact upstream commit recorded in revisions.conf (the
"known-good" revision the maintainer tested), so a fresh ./setup.sh is always
reproducible. update.sh compares the installed revision against the pinned one
and rebuilds only what differs — it never silently tracks moving upstream. Qt
itself is a fixed toolchain — bump it with ./setup.sh --qt-version X.
To deliberately track newer upstream (after testing it yourself), run
./update.sh --update-sources: it fetches the latest default-branch commit of
every component, rewrites revisions.conf, and rebuilds to the new pins. Commit
the bump afterwards.
update.shrebuilds sources only. To refresh the shipped configs/hooks after a repo change (e.g. the lock-restore fix), re-run the config deploy:./setup.sh --skip-apt --skip-qt --skip-fonts --yes.
| Flag | Effect |
|---|---|
--check |
read-only status report (installed vs pinned vs upstream) |
--yes |
apply without prompting |
--force |
rebuild pinned revisions even when already installed |
--update-sources |
bump revisions.conf to latest upstream, then rebuild |
--no-restart |
keep the running shell service as-is |
./uninstall.sh # everything except Qt
./uninstall.sh --purge-qt # also remove /opt/qt* (~2 GB freed)User configs are preserved at ~/.config/caelestia-ubuntu-uninstalled-<date>.
GNOME is never modified by either script.
- Black screen at login / no bar: check
systemctl --user status caelestia-shellandjournalctl --user -u caelestia-shell -e. qsIPC binds do nothing: ensure no globalLD_LIBRARY_PATHpoints at an old Qt; the binary's baked RPATH resolves Qt on its own.hyprctl configerrorslooks wrong: runhyprctl reload.- Lock screen doesn't appear after lid resume / frozen "lock screen died" screen: the installer ships
misc.allow_session_lock_restore = trueplus the systemd-sleep hooks that re-acquire the Caelestia lock on wake — if you still hit it, the hooks were templated with the installing user's id at install time. Re-run./setup.sh --yesto re-deploy them if your uid isn't 1000. hyprlockexits immediately when run manually: the repo now ships a valid~/.config/hypr/hyprlock.conf, but hyprlock can't lock while Caelestia already holds the session lock (that's normal — Super+L is the Caelestia lock).- Missing Calculator action in the launcher:
sudo apt install qalculate(theqalcCLI, not just the library). - Wayland-native Qt 6.11 apps and GNOME apps are unaffected by this install —
only
qsuses the/opt/qt*toolchain.
Repository scripts are MIT-licensed. Installed upstream components keep their own
licenses — see LICENSE.





