Gtkx
GTKX
The React framework for Linux.
Write native GNOME applications with React and TypeScript.
Real Adwaita and GTK4 widgets with standard web tooling.
Homepage · Documentation · Examples · Contributing
The Tasks app you build in the tutorial.
#Demo
This app starts with an Adwaita application shell, renders native GTK4 widgets inside it, and uses ordinary React hooks and events:
import * as Gtk from "@gtkx/gi/gtk";
import { AdwApplication, AdwApplicationWindow, AdwHeaderBar, AdwToolbarView } from "@gtkx/jsx/adw";
import { GtkBox, GtkButton, GtkLabel } from "@gtkx/jsx/gtk";
import { createRoot, quit } from "@gtkx/react";
import { useState } from "react";
const Counter = () => {
const [count, setCount] = useState(0);
return (
<AdwApplicationWindow
title="Hello GTKX"
defaultWidth={400}
defaultHeight={300}
onCloseRequest={quit}
>
<AdwToolbarView topBar={<AdwHeaderBar />}>
<GtkBox
orientation={Gtk.Orientation.VERTICAL}
spacing={20}
marginTop={40}
marginBottom={40}
marginStart={40}
marginEnd={40}
valign={Gtk.Align.CENTER}
halign={Gtk.Align.CENTER}
>
<GtkLabel cssClasses={["title-1"]}>Welcome to GTKX!</GtkLabel>
<GtkLabel cssClasses={["title-2"]}>{`Count: ${String(count)}`}</GtkLabel>
<GtkButton
label="Increment"
onClicked={() => setCount((c) => c + 1)}
cssClasses={["suggested-action", "pill"]}
/>
</GtkBox>
</AdwToolbarView>
</AdwApplicationWindow>
);
};
const App = () => (
<AdwApplication>
<Counter />
</AdwApplication>
);
createRoot().render(<App />);
This is the hello-world example, with app.tsx and index.tsx combined into a single snippet. @gtkx/gi and @gtkx/jsx are per-project bindings generated by the CLI, not packages you install from npm.
#Why GTKX
#Adwaita-first application development
GTKX uses Adwaita as the foundation for applications, windows, navigation, dialogs, and adaptive layouts, with the complete GTK4 toolkit underneath. It adds a declarative React layer and an integrated TypeScript toolchain to the GNOME platform:
- a React reconciler that exposes every GObject as a JSX element,
- a CLI for scaffolding, development, and production builds,
- a dev server with Fast Refresh that patches your running UI in place,
- CSS-in-JS styling, React Hook Form-powered Adwaita controls, gettext-backed react-i18next localization, React Spring animations, React Navigation stack, tab, drawer, and split view navigators, and high-level list, grid, and dialog components,
- a Testing Library-style API for querying and driving your widgets in tests,
- and a Model Context Protocol (MCP) server that exposes your live app to AI agents.
#Native GNOME widgets, without a compatibility layer
React Native and similar frameworks hide the native toolkit so one API can run everywhere. GTKX renders real Adwaita and GTK4 widgets and exposes any other GObject-Introspection library on your system. It is GNOME-native and Linux-only by design.
#Why Node.js, and why generated bindings
GTKX runs on Node.js, which puts native modules, the npm ecosystem, and the tooling built for Node.js APIs within reach. GJS is GNOME's own runtime, built on SpiderMonkey rather than V8; node-gtk runs on Node.js but is lightly maintained, on the older nan/V8 ABI rather than N-API, and still centered on GTK3. The Why GTKX guide covers what running on Node.js means day to day.
GTKX generates the TypeScript types and native FFI calls from the same GObject-Introspection data, so the types cannot drift from the calls they back. Adw-1 is the sole default GIR root; its GIR include pulls in Gtk-4.0, so codegen covers both complete API surfaces. Neither belongs in a GTKX 2 libraries list.
At runtime, the native Rust core calls straight into the system Adwaita, GTK4, and GLib libraries through libffi, without loading libgirepository at all.
#Quick start
GTKX is Linux-only and needs Node.js 26.7 or later. See Requirements.
Scaffold a new app with the create-gtkx initializer:
npm create gtkx@beta
The same command works with other package managers: pnpm create gtkx@beta or yarn create gtkx@beta.
Then run your new app:
cd my-app
npm run dev
To go further, follow the tutorial.
#Documentation
The documentation at gtkx.dev includes a step-by-step tutorial that builds a complete GNOME app, from scaffolding to packaging and shipping, plus guides and a full API reference.
#Requirements
GTKX is Linux-only. You need:
- Linux with the Adwaita (1.8 or later), GTK4 (4.20 or later), and GLib development libraries
- Node.js 26.7 or later
The @gtkx/native addon ships prebuilt for x64 and arm64 glibc Linux; other targets need to build it from the GTKX repository, which requires a Rust toolchain.
#Examples
Explore the example apps:
hello-world: the Adwaita counter above.gtk-demo: the official GTK4 widget showcase in an Adwaita application shell, covering lists, dialogs, gestures, CSS, and OpenGL.browser: an Adwaita browser built aroundWebKitWebView.animations: an Adwaita showcase for@gtkx/animated, with React Spring animations driven by the GTK frame clock.navigation: a tour of@gtkx/navigation, React Navigation's stack, tab, and drawer navigators rendered with libadwaita.tutorial: the Tasks app the documentation builds.
#Status
GTKX is stable and ready for production use.
#Contributing
Contributions are welcome. The Contributing docs cover GTKX's architecture, tech stack, development setup, and testing workflow. See CONTRIBUTING.md for contribution and release procedures, the Code of Conduct, and the security policy. Building the repo needs Node.js 26.7 or later, pnpm, and a Rust toolchain.
#License
GTKX is licensed under MPL-2.0.