gtkx

Installation
SKILL.md

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);

See styling and portals.

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 quit from @gtkx/react to close the application
  • Async GTK uses Promise methods, catch NativeError for failures

References

Related skills
Installs
2
Repository
knoopx/pi
GitHub Stars
46
First Seen
Apr 18, 2026