Linux (GTK 4)
Tier 2 · Demi-supportedlinux-gtk renders GTK 4 widgets styled by libadwaita,
through gtk4-rs. It is the default recommendation on Linux: it’s the
toolkit Ubuntu, Fedora and Debian install by default.
Getting started
GTK 4.10+ and libadwaita 1.5+ are required (Ubuntu 24.04 and Fedora 40 both satisfy this):
sudo apt install libgtk-4-dev libadwaita-1-dev pkg-config # Debian/Ubuntu
sudo dnf install gtk4-devel libadwaita-devel pkgconf # Fedora
cargo install day-cli
day new app my-app --toolkit linux-gtk
cd my-app
day launch -p linux-gtk
Add libwebkitgtk-6.0-dev if you use the web view piece. day doctor --toolkit gtk probes
GTK 4, libadwaita, glib-compile-resources, and the packaging tools (flatpak-builder,
linuxdeploy, linuxdeploy-plugin-gtk); it does not check WebKitGTK.
day pack -p linux-gtk # single-file .flatpak AND a portable .appimage
day pack produces both formats by default. The flatpak runtime supplies GTK itself
(org.gnome.Platform), so that bundle carries only your app and its assets; A user installs it with
flatpak install ./my-app-1.0-linux-gtk-x86_64.flatpak. The AppImage carries its own GTK, so a user
marks it executable and runs it.
Caveats
- libadwaita is required. The window, navigation, tabs, dialogs and animations are all Adwaita types; a plain-GTK build is not a supported configuration.
GtkVideoneeds a GStreamer media backend in the GTK build. Distro packages ship one; Homebrew’s gtk4 does not, so the media piece shows GTK’s own “no media backend” error onmacos-gtk.- Lottie and map have no GTK arm; each renders its placeholder.
cover()presents as a topmost window-sized child (no transition, programmatic dismissal only). - The combo box uses
GtkComboBoxText, deprecated in GTK 4.10 but kept because GTK has no editable replacement yet. - A
progressnode picks its widget at realize time:progress(f)becomes aGtkProgressBarandspinner()aGtkSpinner. A node that starts indeterminate will not turn into a bar on a later value change; use separate nodes if you need both. - Canvas text uses cairo’s toy text API, not Pango, so complex-script shaping inside a
canvasis weaker than in alabel. - GTK on macOS and Windows (
macos-gtk,windows-gtk) exists for development convenience only (Tier 4);day packskips them, and the accessibility tree is absent (GTK’s a11y bridge is Linux-only).windows-gtkbuilds against MSYS2’s GTK 4 with a GNU Rust toolchain (setup); there is no WebKitGTK 6 for Windows, so the web view is a placeholder there, and bundled custom fonts don’t register with Pango.
What each piece becomes
The generated coverage matrix, checked in CI, covers every backend; this table adds links and notes.
| Day piece | GTK widget |
|---|---|
column / row / nav_stack / section | GtkFixed (Day owns layout) |
label | GtkLabel |
button | GtkButton |
toggle | GtkSwitch |
slider | GtkScale |
text_field | GtkEntry |
text_area | GtkTextView in a GtkScrolledWindow |
picker().menu() | GtkDropDown |
picker().segmented() | linked GtkToggleButtons |
picker().inline() | grouped GtkCheckButtons (GTK 4’s radio) |
progress(f) | GtkProgressBar |
spinner() | GtkSpinner |
divider | GtkSeparator |
scroll | GtkScrolledWindow |
list | GtkListView (recycling, signal factory) |
nav (split) | GtkPaned |
nav (stack) | AdwNavigationView |
nav_menu | GtkListBox (.navigation-sidebar) |
tabs | AdwViewStack + linked toggle buttons |
image | GtkPicture |
vector | GtkPicture showing the raster cache PNG (.tint recolors the pixels) |
cover() | emulated: a topmost window-sized child (no transition, programmatic dismissal only) |
canvas | GtkDrawingArea (cairo) |
| dialogs / alerts / prompts | AdwAlertDialog |
| file dialogs | GtkFileDialog |
| menu bar / context menus | GtkPopoverMenuBar / GtkPopoverMenu |
external activity() | GtkSpinner |
external combobox() | GtkComboBoxText (with entry) |
external search_field() | GtkSearchEntry |
external date_picker() | GtkCalendar, in a GtkMenuButton popover when compact |
external time_picker() | linked GtkSpinButtons |
external webview() | WebKitWebView (WebKitGTK 6.0) |
external media() | GtkVideo |
Text measurement builds a Pango layout on the label’s styled context rather than calling
gtk_widget_measure, because a GtkFixed child’s size request would otherwise ratchet upward and
never shrink.



