Linux (GTK 4)
linux-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 checks the
whole set.
day pack -p linux-gtk # single-file .flatpak
The flatpak runtime supplies GTK itself (org.gnome.Platform), so the bundle carries your app
and its assets, not the toolkit. flatpak install ./MyApp-1.0-gtk-x86_64.flatpak
is all a user needs.
Caveats and special considerations
- libadwaita is not optional. 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.- No Lottie, no map on this backend — 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 deliberately: no editable replacement exists 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 — no packaging, and no accessibility tree (GTK’s a11y bridge is Linux-only).
What each piece becomes
| Day piece | GTK widget |
|---|---|
column / row / 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 |
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 own styled context rather than calling
gtk_widget_measure, because a GtkFixed child’s size request would otherwise ratchet upward and
never shrink.



