gtkx
GTKX Skill
GTKX renders React components as native GTK4 widgets on Linux: @gtkx/react → @gtkx/ffi → @gtkx/native → GTK4/GLib.
Project Setup
npx @gtkx/cli@latest create my-app
# Runs: npm run dev | npm run build | npm test (vitest + Xvfb)
Generates src/app.tsx, src/dev.tsx (HMR), src/index.tsx. Entry calls render(<App />, pkg.gtkx.appId). See getting-started.
Essential Patterns
Controlled Input
Widgets require explicit two-way binding — not React state alone:
const [text, setText] = useState("");
<GtkEntry text={text} onChanged={(e) => setText(e.getText())} />;
// GtkSwitch: return true from onStateSet to accept change
Compound Components
Slots and child positioning use compound components (auto-generated from GIR):
<AdwToolbarView>
<AdwToolbarView.AddTopBar><AdwHeaderBar /></AdwToolbarView.AddTopBar>
</AdwToolbarView>
<GtkHeaderBar>
<GtkHeaderBar.PackStart><GtkButton iconName="go-previous-symbolic" /></GtkHeaderBar.PackStart>
<GtkHeaderBar.TitleWidget><GtkLabel label="Title" /></GtkHeaderBar.TitleWidget>
</GtkHeaderBar>
Common compound components: AddTopBar/AddBottomBar (ToolbarView), PackStart/PackEnd (HeaderBar/ActionBar), StartChild/EndChild (Paned/Flap). See widgets for the full catalog.
Layout and Lists
GtkBox (linear), GtkGrid (GtkGrid.Child), GtkStack (GtkStack.Page), GtkPaned (GtkPaned.StartChild), GtkScrolledWindow. Virtual lists use { id, value }[] items with renderItem; add children for tree mode. See widgets.
Styling and Portals
import { css } from "@gtkx/css";
<GtkButton
cssClasses={[
css`
background: #3584e4;
&:hover {
background: #1c71d8;
}
`,
]}
/>;
const win = useProperty(useApplication(), "activeWindow");
open && win && createPortal(<GtkAboutDialog programName="My App" />, win);
Adwaita Skeleton
<AdwApplicationWindow
title="App"
defaultWidth={800}
defaultHeight={600}
onClose={quit}
>
<AdwToolbarView>
<AdwToolbarView.AddTopBar>
<AdwHeaderBar>
<GtkHeaderBar.PackStart>
<GtkButton iconName="open-menu-symbolic" />
</GtkHeaderBar.PackStart>
<GtkHeaderBar.TitleWidget>
<AdwWindowTitle title="App" />
</GtkHeaderBar.TitleWidget>
</AdwHeaderBar>
</AdwToolbarView.AddTopBar>
<MainContent />
</AdwToolbarView>
</AdwApplicationWindow>
See widgets, examples, and tutorial.
Key Constraints
- GTK is single-threaded — all widget operations on main thread
- Virtual list items must be stable objects (immutable data patterns)
- Use
quitfrom@gtkx/reactto close the application - Async GTK uses Promise methods, catch
NativeErrorfor failures
References
- Widget API: widgets · examples
- Core docs: introduction · getting-started · ffi-bindings · styling · portals · testing · cli · mcp
- Tutorial: window & header bar · styling · lists & data · menus & shortcuts · navigation & split views · dialogs & animations · settings & preferences · deploying
More from knoopx/pi
podman
Manages containers, builds images, configures pods and networks with Podman. Use when running containers, creating Containerfiles, grouping services in pods, or managing container resources.
125jujutsu
Manages version control with Jujutsu (jj), including rebasing, conflict resolution, and Git interop. Use when tracking changes, navigating history, squashing/splitting commits, or pushing to Git remotes.
119nix-flakes
Creates reproducible builds, manages flake inputs, defines devShells, and builds packages with flake.nix. Use when initializing Nix projects, locking dependencies, or running nix build/develop commands.
54scraping
Fetches web pages, parses HTML with CSS selectors, calls REST APIs, and scrapes dynamic content. Use when extracting data from websites, querying JSON APIs, or automating browser interactions.
48jscpd
Finds duplicate code blocks and analyzes duplication metrics across files. Use when identifying copy-pasted code, measuring technical debt, or preparing for refactoring.
45yt-dlp
Downloads videos from YouTube and other sites using yt-dlp. Use when downloading videos, extracting metadata, or batch downloading multiple files.
42