libLuna
The library Luna's windows stand on. It draws the scene, shapes text, handles input and translations. It doesn't need GTK, Qt or GObject — just Rust and Wayland.
Counterpart of: GTK or Qt.
The libLuna project
libLuna is a small GUI toolkit written in pure Rust. Together with the Luna desktop and the Selene compositor, it forms one coherent desktop — from drawing a button to putting a window on screen. No GTK, no Qt, no GObject. In plain terms: fewer layers to work around.
Pure Rust · Wayland · MPL-2.0 · no CDN fonts, no trackers
Three layers
GTK / GNOME / Mutter. Qt / KDE Plasma / KWin. Ours: libLuna / Luna / Selene. Each layer does one job and doesn't pretend to do all of them.
The library Luna's windows stand on. It draws the scene, shapes text, handles input and translations. It doesn't need GTK, Qt or GObject — just Rust and Wayland.
Counterpart of: GTK or Qt.
What you see after logging in: panel, launcher, settings, files, terminal, lock screen. One coherent shell where every element speaks the same language.
Counterpart of: GNOME or KDE Plasma.
The Wayland compositor. It accepts windows, arranges them, routes keyboard and pointer input, handles monitors and X11 windows. Built without smithay — on its own thin layer.
Counterpart of: Mutter or KWin.
The reason
The idea didn't come from disliking GTK. It came from a question: what if we want a desktop that is small, fast and entirely ours?
GTK4 with libadwaita drags in GObject, glib and manual reference counting. For a small desktop that's more machinery than we actually need.
Rust bindings add another bridge to keep an eye on. We wanted fewer moving parts, not more.
Great for tools, but they don't model shell chrome: CSD title bars, sidebars, path bars and popovers.
Rust from widget to compositor. No two memory models, no FFI in the middle, no packaging surprises.
Colours and control geometry are tokens, not constants scattered across widgets. A theme can reshape the UI without touching code.
Small code, small binary, predictable performance. It's easier to fix something you can hold in your head — and wrote yourself.
“libLuna isn't trying to be GTK. It's trying to be good enough for Luna — and only that.”
Architecture
Four levels, one direction of dependency. Upper layers don't need to know what lower ones do — that's the whole trick.
Selene doesn't need to know an app uses libLuna. libLuna doesn't need to know how DRM works. Each layer knows only its own job.
No spin
The project is moving. We'd rather show the real state than promise a desktop that isn't there yet.
The full, living protocol list: docs/compositor.md.
Screenshots
Every screenshot comes from working code — either the offline preview or a live Selene session.
Try it
You need Linux, a stable Rust toolchain and a Wayland compositor. Selene can run alongside your current session without taking over the screen.
# build the whole workspace and run the demo
git clone https://git.paganlinux.eu/luna.git
# or from the mirror: git clone https://github.com/mijsys/libLuna.git
cd libLuna
cargo build --workspace
cargo run -p luna-demo
# no compositor: render a preview to PNG
cargo run -p luna-demo --bin render -- docs/images/out.png
/dev/input.For a test run next to your current session: SELENE_BACKEND=nested selene. Details in de/README.md.
# install into a directory — nothing touches the system
./scripts/install.sh --destdir /tmp/luna-test --prefix /usr
# inspect the plan first, then install system-wide
./scripts/install.sh --dry-run
sudo ./scripts/install.sh --prefix /usr