This is Part 1 of a series that takes a GNOME application from an empty directory to acceptance into GNOME Circle. Each post is self-contained, but the series follows a single arc — and a real app — through every stage of the journey.
Why GNOME
If you're building a desktop Linux application in 2026, you've got choices. KDE Plasma has Kirigami. Elementary has Granite. You can reach for Electron, Tauri, or a dozen other cross-platform toolkits and call it a day.
I chose GNOME because of what it feels like to use. The GNOME desktop provides a clean, distraction-free approach to computing. Its consistency rivals early macOS — there's a feeling that everything is in its place. When I started building Moments, my photo management app, that consistency carried over into the development experience in a way I didn't expect. The provides distribution. for current versions.
Install GNOME Builder
GNOME Builder is the IDE purpose-built for GNOME development. It understands Meson, Flatpak manifests, and the GNOME SDK. It can build your application inside the Flatpak sandbox, run it, and provide code intelligence — all without you manually configuring build environments.
flatpak install flathub org.gnome.Builder
Builder isn't the only option. You can use VS Code, Neovim, or any editor you prefer — I'll cover that setup in a later post on developer experience. But Builder eliminates the most configuration friction for getting started, and it's what I'd recommend for your first project.
Verify the toolchain
Open a terminal inside the Flatpak SDK environment to confirm everything is in place:
# Enter the SDK environment
flatpak run --command=bash org.gnome.Sdk//50
# Inside the SDK shell:
rustc --version
cargo --version
pkg-config --libs gtk4
pkg-config --libs libadwaita-1
You should see a recent stable Rust version and successful pkg-config output for both GTK4 and libadwaita. If any of these fail, the SDK or Rust extension didn't install correctly — reinstall them before continuing.
A note on host development
You can also develop on your host system by installing the GTK4 and libadwaita development packages directly:
# Fedora
sudo dnf install gtk4-devel libadwaita-devel
# Arch
sudo pacman -S gtk4 libadwaita
# Ubuntu/Debian (may lag behind on versions)
sudo apt install libgtk-4-dev libadwaita-1-dev
This gives you faster compile times and a tighter edit-compile-run loop, which matters during active development. Many Rust/GTK developers work this way day-to-day, using host-installed libraries for rapid iteration and Flatpak builds for testing and release.
The risk is version drift between your host libraries and the Flatpak SDK. If you go this route, check which GTK4 and libadwaita versions your host provides and compare them to the GNOME SDK you're targeting. As long as your host version is equal to or newer than the SDK version, you're fine. If it's older, you'll hit missing APIs.
My recommendation: start with Flatpak-only builds until you've got a working app, then add host builds as an optimisation once you understand the version boundaries.
The tools you will be using
Before we start writing code in Part 2, here's a brief orientation to the tools that'll appear throughout this series. You don't need deep knowledge of any of them yet — just awareness that they exist and what role they play.
— A markup language for defining GTK user interfaces. Blueprint compiles to the XML that GTK's GtkBuilder expects, but it's dramatically more readable. You can also build your entire UI in Rust code without Blueprint — we'll cover both approaches.
— The metadata standard that app stores (including Flathub) use to display your app's name, description, screenshots, and release notes. You'll need to get this right for Flathub acceptance — Part 9 covers it.
Workbench — A playground app for experimenting with GTK widgets, CSS, and Blueprint templates. If you want to test a UI idea without rebuilding your whole app, Workbench is where you do it. Grab it from Flathub.
What we're building
Part 2 opens with introducing the app we'll build throughout this series. It won't be a toy counter or a TODO list — it'll be something with enough complexity to hit real architectural decisions, real packaging challenges, and real Flathub review feedback.
Every post will be self-contained enough that you can follow along building your own app. The problems we'll solve — state management, async operations, data persistence, adaptive layouts, packaging — are universal to any non-trivial GTK application. We're documenting the actual experience of taking a GNOME app from zero to Circle, including the parts that aren't in any documentation.
What comes next
Before we build a window, we need to understand the type system underneath it. Every widget, every signal, every property binding in GTK is built on GObject — and the way GObject maps to Rust is the single biggest conceptual hurdle for developers coming from other Rust backgrounds.
In Part 2, we'll build a simple data model from scratch and use it to understand GObject's inner/outer type pattern, properties, signals, and property bindings. No GTK widgets yet — just the foundation that makes everything else click once we start building the actual app in Part 3.
SOCIAL SHARE CARD GENERATOR