libLuna About the project
Accent colour like in Luna Settings

Appearance is tokens, not constants scattered across code. Changing the accent here works just like in Luna — on this page only.

PL EN

The libLuna project

A desktop we're
writing ourselves.

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

The Luna Settings window in the light theme: sidebar, cards and switches drawn by libLuna.
Offline preview — no compositor

Three layers

One puzzle, three names

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.

Toolkit

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.

Rust tiny-skia Wayland
Environment

Luna

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.

shell apps greeter
Compositor

Selene

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.

Wayland DRM/KMS XWayland

The reason

Why not just GTK?

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?

01

GTK does the job, but it's heavy.

GTK4 with libadwaita drags in GObject, glib and manual reference counting. For a small desktop that's more machinery than we actually need.

02

Qt is brilliant, but enormous.

Rust bindings add another bridge to keep an eye on. We wanted fewer moving parts, not more.

03

egui and iced think differently.

Great for tools, but they don't model shell chrome: CSD title bars, sidebars, path bars and popovers.

04

We want one stack.

Rust from widget to compositor. No two memory models, no FFI in the middle, no packaging surprises.

05

We want a swappable look.

Colours and control geometry are tokens, not constants scattered across widgets. A theme can reshape the UI without touching code.

06

We want to know what we have.

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

How it stacks up

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

What works, and what doesn't yet

The project is moving. We'd rather show the real state than promise a desktop that isn't there yet.

Works

  • libLuna: widgets, light/dark/auto themes and 9 accent colours.
  • Multilingual pl/en/de without gettext — one file per language.
  • Luna: panel, launcher (list, grid, carousel), settings, files, terminal.
  • Luna: OSD, notifications, lock screen and login greeter.
  • Selene: xdg-shell, wlr-layer-shell, clipboard, drag & drop and multi-monitor.
  • Selene: DRM/KMS, evdev input, X11 windows through XWayland and XWM.

Not yet

  • GPU and dmabuf — zero-copy for Vulkan/EGL clients. Rendering is CPU today.
  • Client-side cursors and middle-click paste.
  • IME / text-input-v3 for comfortable CJK input.
  • Fractional scaling and full HiDPI without blur.
  • xdg_activation — a new window can still end up behind another.
  • AT-SPI accessibility — important, but scheduled later.

The full, living protocol list: docs/compositor.md.

Screenshots

This is what it looks like

Every screenshot comes from working code — either the offline preview or a live Selene session.

Try it

Run it yourself

You need Linux, a stable Rust toolchain and a Wayland compositor. Selene can run alongside your current session without taking over the screen.

bash · demo
# 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

What you'll need

  • Linux with Wayland — Selene or another compositor.
  • A stable Rust toolchain (rustup is enough).
  • For a DRM session: a free DRM master and access to /dev/input.

For a test run next to your current session: SELENE_BACKEND=nested selene. Details in de/README.md.

bash · test install
# 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